arkenfox / user.js

Firefox privacy, security and anti-tracking: a comprehensive user.js template for configuration and hardening
MIT License
9.44k stars 508 forks source link

CSS @supports fingerptinting #1604

Closed atomGit closed 1 year ago

atomGit commented 1 year ago

check this out: https://noscriptfingerprint.com/

every time i refreshed or reloaded the page the fingerprint was the same

i don't know how problematic/worrying that actually is so i'd like to hear comments, but that site led me to a hidden pref...

layout.CSS.supports-rule.enabled (boolean)

...and setting that to false seems to mess with the ability of css @supports to fingerprint - i now get a different value every time i refresh (no reload necessary), but the FP is still the same at every browser restart

the jackasses responsible for css have gone out of their fucking minds IMO - you can now create complex games and web pages with only css - it's becoming JS-like

Thorin-Oakenpants commented 1 year ago

CSS has always been fingerprintable, ever since it was first introduced./ What makes you think it is special or new?

atomGit commented 1 year ago

because i wasn't aware it was fingerprintable

atomGit commented 1 year ago

so what's the point of rfp if it can be circumvented by something as stupidly simple as this?

KOLANICH commented 1 year ago

Its fingerprintability can be greatly reduced to feature detection if browser vendors code the browsers so that resources are always fetched even if not needed. Also fingerprinting can be deincentivized by putting limits on conditional queries and disabling css wholly.

But browser vendors prefer not to do it. Because if they did it, the adversaries interested in elimination of companies making unfriendly browsers will just intentionally create non-fingerprinting stylesheets that are malfunction in that exact brioser and putting it into own powerful websites and then claim dropping support of the unfriendly browser by claiming that it is a piece of shit not following the specs and breaking websites. For the first countermeasure it'd be a stylesheet downloading GiBs of pics. For the second one it'd be a stylesheet violating the set limits. If limits got adjusted, it'd become a yet ankther fingerprinting vector.

A mitigatiin for the first countermeasure should be downloading not the zillions of content, but the specific multip,e of the one normally downliaded:

  1. estimate the amount of normally downloaded content by downloading a few randomly chosen subsample of all the content (including a selected one), and extrapolating its size to all, the content
  2. randomly place selected content within the remaining part of the content
  3. download all the ckntent, discard non-selected one.

As a countermeasure website owners can detect the browsers downloading sets of content that must never be downloaded simultaniously when CSS is working and then discriminate against users of such browsers by blocking access on the eexcuse of overloading the website.

A countermeasure for browser vendors may be to detect such CSS and to present a user with an emulation screen like the one in devtools, allowing to choose a fake device frofile to present to a website, before downloading the website content dependent on media queries.

Thorin-Oakenpants commented 1 year ago

so what's the point of rfp if it can be circumvented by something as stupidly simple as this

rfp covers css

edit: to be more precise, it protects some css metrics that can leak the real value from RFP protected JS metrics, and even protects some purely css metrics - and most css is equivalency

KOLANICH commented 1 year ago
  1. external fonts are covered by the arkenfox preset. fonts detection will always report all the fonts are present locally because they are never used from the Net.
  2. http headers can be altered with WebRequest, though IDK to which extent. It'd be nice to unify headers order for all the browsers.
  3. Accept-Encoding cannot really be faked into misreporting support of compression, but compressions used in browsers are pretty stable for a long time, so they should carry very little info. The order of the preference may differ, but IMHO there is no sense to prefer anything except br the most.
  4. Accept-Language should be set into a value the same for all the browsers.
  5. @supports only fingerprints browser version. I think it makes sense to hide that info, but Mozilla has even stopped hiding it from User-Agent header. While putting a fake value into a UA header doesn't exclude it from being fingerprinted, it just makes it a low-hanging fruit and also increases the accuracy, since between releases the most of code is unchanged, so detecting version by sets of supported and features can only give ranges ov versions during which the sets haven't changed.
  6. the most dangerous thing there is screen dimensions fingerprinting.
  7. that demo and the article omit such important topics as mouse pointer and keyboard typing tracking, which can carry biometric information.
atomGit commented 1 year ago

@supports only fingerprints browser version

i don't think it has anything to do with version - it can be used to detect what browser is being used and what some of its capabilities are regarding very specific CSS capabilities, as well as font detection

go here: https://noscriptfingerprint.com/ and then click the 'See more details' link after the fp is generated

KOLANICH commented 1 year ago

it can be used to detect what browser is being used and what some of its capabilities are regarding very specific CSS capabilities

What browser means exactly browser version. Different versions of the same browser are different but similar browsers, and different browser engines can be considered as different versions of some generic browser.

rusty-snake commented 1 year ago

i don't think it has anything to do with version

And supported CSS features are independent of the version? For 99% of the users who do not play with browser internals, the browser version (and rollout via experiments) is the only thing that influences CSS features.

KOLANICH commented 1 year ago

CSS capabilities are usually changed when they are implemented jn a new browser version.

KOLANICH commented 1 year ago

And about screen fingerprinting, here is the idea:

While putting a lot of selectors for each dimension can be bloat, and while one cannot run code on client, one can run code on server, so there is no need to use so many selectors.

  1. a webpage with 3 complementary selectors and URIs is generated based on whether a screen size is greater, lower or equal to the pivoting value.
  2. the webpage also contains either a header or a meta tag that reloads it after some timeout. Initially a very small value is used. If it is not enough, it will be increased. Overall count of page reloads is limited my the height of the binary tree + some requests used for adjusting timeouts and border zone.
  3. if the signal received that the screen dimension is exactly pivot value: finish
  4. if none of the signals has been received, increase reload timeout, for example using binary search again.
  5. if mutually excluding signals are received - increase the border zone around the pivot. Initially border zone is of width 0.
  6. if a signal > or < is received: compute the next pivot using binary search. The new pivot will be used after the page reload.
KOLANICH commented 1 year ago

Also I wonder if state tracking for fingerprinting can be implemented without server-side code. I wonder what happens if a CSS selector displays an iframe. If that iframe is loaded and executed only after being set with display other than none, I wonder if one can nest iframes to record state within iframe hierarchy. The pages for frames can be pregenerated and put on a static hosting. To avoid exponential expansion one can build a decision tree model. Browser features are usually introduced sequentially so we can make some realistic assumptions:

  1. the browser is from the set of major browsers, the version of the browser is from a small-enough set of versions.
  2. if a later feature is present, the previous ones are also present, except the ones that had been retracted.
  3. for each browser version its probability and the set of features are known.

so the algo is the following:

  1. split the (sub)distribution into the equiprobable parts by a pivot version.
  2. check whether the browser has a greater or a lower version using the non-retracted features. If one cannot use only non-retracted features, use the retracted features, but also the non-retracted features of the version of the browser where they have been retracted.
  3. the final iframe contains an image sending the info to the interested party.
Thorin-Oakenpants commented 1 year ago

i don't think it has anything to do with version - it can be used to detect what browser is being used and what some of its capabilities are regarding very specific CSS capabilities, as well as font detection

you can't hide your engine (active + passive), you can't hide your version (active), you can't hide your OS (active + passive) - capabilities are version specific and are thus equivalency, fonts are equivalency if you restrict to system fonts ((mostly, there is still some entropy due to OS versioning). You also can't hide your engine version (active) and it's not a big deal if you were to leak that in css only (passive: depends on what features were added when and if it's feasible to detect them) - you should be up to date. Version is really low hanging fruit TBH and a non-factor in active (your version automagically reveals itself in JS css properties, htmlelement properties, and so on). Even RFP in FF doesn't hide the version on desktop, because numbers matter - when you have 200mn FF users, the buckets are large enough as to make the metric useless (UA headers, JS)

With a metric has entropy, you need to distinguish between two threats here

CSS capabilities are usually changed when they are implemented jn a new browser version

KOLANICH is correct - it's called equivalency. I already said most css is equivalency. You really do need to ascertain the entropy first before lumping everything in a "OMG .. fingerprint"

Thorin-Oakenpants commented 1 year ago

this is not the place to discuss FPing theory ... locking

https://github.com/arkenfox/user.js/wiki/3.3-Overrides-[To-RFP-or-Not]#-summary

I am not interested in debating issues with non-experts.

“One of the major difficulties Thorin experienced in her relationship with the Peacock was learning to distinguish between him pretending to be stupid just to get people off their guard, pretending to be stupid because he couldn't be bothered to think and wanted someone else to do it for him, pretending to be outrageously stupid to hide the fact that he actually didn’t understand what was going on, and really being genuinely stupid." - Douglas Adams

I am not directly calling either of you a non-expert, but I am not prepared to discuss anything in depth here. It annoys me and eats my time and attention - hence the wiki entry so people fuck off on the topic. I have a TZP repo - but do not interpret that as an open invitation to bombard me there with mundane questions