Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

privacy.resistFingerprinting #56

Open
allo- opened this Issue Dec 2, 2016 · 12 comments

Comments

2 participants

@allo- allo- added easy setting labels Dec 2, 2016

@allo- allo- closed this in aa55dce Jan 25, 2017

@Thorin-Oakenpants

This comment has been minimized.

Copy link

Thorin-Oakenpants commented Oct 1, 2017

https://bugzilla.mozilla.org/show_bug.cgi?id=1329996 is the meta ticket
https://bugzilla.mozilla.org/show_bug.cgi?id=418986 is the original ticket that created the pref

The one you have linked to is just a UI option to be dealt with when RFP is much more mature. It's also not a TOR thing - its been in FF since FF41 - "setting coming from the tor-browser" is not right IMO. All this stuff is being baked into Firefox itself - I wouldn't even mention tor, at best just mention and link to the tor uplift - https://wiki.mozilla.org/Security/Tor_Uplift/Tracking


You need to rethink this IMO.

privacy.resistFingerprinting (RFP for short) is part of the Tor Uplift Project and is more than just a simple setting. It also depends on when various patches tied to RFP are landed. Originally RFP was going to flip prefs on people and enforce their settings, but this was problematic. Instead, RFP changes are hard-coded to (generally) bypass any similar existing pref. Often the result is different - thus changing your fingerprint.

Here is a tracking issue: ghacksuserjs/ghacks-user.js#7

As you can see, starting from FF55 on, a lot of patches "clash" with existing prefs. I haven't looked at your collection - but the ghacks user.js is rather extensive - any items that RFP clash with are now in an "RFP alternative" section

Here is a discussion on these "clashes" - ghacksuserjs/ghacks-user.js#222

some examples:

  • geo.enabled if false disables the API but the RFP patch instead blocks requests (same as if you clicked deny when a website requests it)
  • dom.netinfo.enabled = if false returns undefined, with RFP it returns "unknown"
    • this is a weird one because on desktop the default is false, and it seems the pref overrides the RFP patch
  • dom.gamepad.enabled if false disables the API, but the RFP patch instead returns an empty array
  • media.video_stats.enabled if false disables the API but the RFP spoofs values (dynamically if needed)
  • dom.w3c_touch_events.enabled if false disabled the Touch API but the RFP patch instead spoofs

and it goes on... now each patch vs pref equivalent may or may not achieve the same result, often the approach taken by the RFP team is different. And how the patch vs pref is handled code wise may mean either one takes precedence over the other. Each pairing has to be checked on it's own, as their is no set rule

If you're not sure where I am going with this .. it is that just turning on RFP is not enough. End users need to make sure relevant prefs are reset in about:config, otherwise their fingerprint is not the same.

It also depends on what prefs you in your UI (and which FF version people are on to throw in the mix as well) - how you handle that in getting the information to people in your UI or how you group things, is up to you. In our use.js we have a RFP ALTERNATIVE and each user.js has a release each stable. Users who disable RFP can flip on the alt section with one character. Same for ESR users.

@allo-

This comment has been minimized.

Copy link
Owner Author

allo- commented Oct 1, 2017

I am note sure what this exactly implies before reading this in more details.

I reopen here now. Fo you have concrete suggestions about the setting or is it a bigger deal to use it correctly?

@allo- allo- reopened this Oct 1, 2017

@allo- allo- removed the easy label Oct 1, 2017

@allo-

This comment has been minimized.

Copy link
Owner Author

allo- commented Oct 1, 2017

Just picking some points for the moment:

geo.enabled if false disables the API but the RFP patch instead blocks requests (same as if you clicked deny when a website requests it)
In general I prefer to use defaults for settings, which ask the user for permission anyway. Blocking silently avoid one bit of information if I get it right, but probably the same bit as when the user chooses "always deny" in the firefox UI.
I guess there could be some tracking via "can I ask or is it always denied", but as this would be quite visible I see not important threat here. The setting is more convenience to avoid the dialog.

End users need to make sure relevant prefs are reset in about:config, otherwise their fingerprint is not the same.
So resist + enable = enabled, resist + disabled = disabled and resist + default = resist-fingerprint?
This is quite a problem, as I am not sure if you can override settings with unset when pasting new lines into prefs.js.
In principle I want to generate fresh profiles, which does not have such problems. But actually it is useful to add stuff to existing profiles as well if you know what you're doing.

So for new profiles it would be a tri-state switch (and hard to explain to users), for existing profiles probably manual work needed. And the best fingerprint probably the one of the tor browser (the more settings are included in resistFingerprint, the better).

I would have said maybe it needs an helper extension, but firefox 57+ extensions won't be able to change "about:config" settings.

@Thorin-Oakenpants

This comment has been minimized.

Copy link

Thorin-Oakenpants commented Oct 1, 2017

not sure if you can override settings with unset

Correct. There is NO way to reset to a pref to default in about:config from a *.js. You could set it to the same value as default, but then it is always in the prefs.js and mozilla would not be able to change it on you if they ever changed the default. This is problematic.

Here is an overview: https://github.com/ghacksuserjs/ghacks-user.js/wiki/1.6-Bulk-Pref-Resetting-[Scratchpad] - besides telling our users to reset stuff in places (wiki, js header, a couple of sections), there's not much more we can do. We're now going to provide some js scripts to reset every pref used in our user.js (then the user.js, or their version they have modified, will reapply everything - the wiki page says it all).

And you are right about extensions not being able to change about:config entries - some are available and will expand. eg they wish to make privacy.resistFingerprinting available in the privacy API (or whatever it's called)

or is it a bigger deal to use it correctl

It's very complicated. If you look at our tracking issue ( ghacksuserjs/ghacks-user.js#7 ) there is an awful lot they have done, more to come, and dozens more not yet files as bugzillas to do later. A lot of these have prefs which essentially do the same thing but the approach and outcome of each can vary, and as I said it's not a case of RFP overrides pref - each one needs to be vetted and tested.

We have it easy, because in the user.js we can flip a single character to enable entire sections such as ESR. We also only apply these to the current release - eg right now it is FF56. Although we do provide versioning of when RFP will come into affect, this is not the same - eg the RFP ALT section only contains prefs that clash or are redundant up to 56 inclusive. Anyone on 57 or 58 is out of luck (except the RFP section gives them all the info they need to know for their version)

The purpose of RFP is make the subset of firefox users with the pref on appear the same when FP'ed. THIS will not happen if users meddle with prefs that cause the FP to change - as per some examples above. Each one they conflict with simply makes them more FP'able and unique.

There is no easy answer for you. I have spend a year+ on this RFP stuff in my spare time, 3 years on the user.js, and had help from a few people. I also have contact with Tor Uplift and the Mozilla uplift team - either on IRC, emails, or bugzilla.

Arthur Edelstein (the main tor uplift guy) on this same discussion of interfering existing prefs - he said in tor they were going to make the prefs hidden in about:config. I said he should lock them as well :) Tor though, only has to worry about a single release - and so do we in a sense - your profile maker has to deal with the entire spectrum

@Thorin-Oakenpants

This comment has been minimized.

Copy link

Thorin-Oakenpants commented Oct 2, 2017

So resist + enable = enabled, resist + disabled = disabled and resist + default = resist-fingerprint

Not quite. Depends on each pairing. And in my example below on the default which can vary on platform. But yes, RFP+ON and PREF+DEFAULT = proper way to use privacy.resistFingerprinting

Here is an example (4 combinations)

Note, the values returned can be: bluetooth, cellular, ethernet, wifi, wimax, other, mixed, unknown, none. Here is the spec: https://developer.mozilla.org/docs/Web/API/Network_Information_API

<body>
<script>console.log(navigator.connection);</script>
</body>
  • RFP off
    • dom.netinfo.enabled=false (desktop default) = undefined
    • dom.netinfo.enabled=true = NetworkInformation { type: "see list above", ontypechange: null }
  • RFP on
    • dom.netinfo.enabled=false = undefined
    • dom.netinfo.enabled=true = NetworkInformation { type: "unknown", ontypechange: null }

Desktop users have a default of false, and in this case it makes no difference. Mobile users have a default of true and again, this makes no difference. In this case the pref to enable or disable the API comes first, but when the API is not disabled, then RFP makes a difference. So end users should have their pref at default. This is kind of a weird example as it only really protects mobile users - kinda

A simpler example would be touch API. Under RFP it rounds/spoofs the coordinates and allows end users to use touch. The pref kills touch dead. BIG difference to JS that detects this. Again, on this example, I would also assume the pref that controls the API to control the effect the RFP has.

🔻 example where prefs make no difference

But not all are to do with disabling APIs. Here is an example that may make more sense. UA (user agent) spoofing and various navigator objects. RFP spoofs all these. Here are some prefs

  • general.useragent.override
  • general.buildID.override
  • general.appname.override
  • general.appversion.override
  • general.platform.override
  • general.oscpu.override
  • general.useragent.locale (although I believe it is intl.accept_languages that is used in the UA)

Now, UA spoofing is leaky and RFP is still not perfect, but lets not go there. And setting your own values is not the same as being in a large set that has enforced values, but lets not go there. RFP in this case overrides these prefs. Set whatever you like, they make no difference. However, the RFP solution is a lot better and fixes leaks that using these prefs do not.

🔸 tl;dr:

It depends on the RFP approach and the pref (eg one that kills an API means the RFP approach generally should never fire). The easiest way to get the full benefit of RFP is to have relevant prefs at default. And that list of prefs is going to become MASSIVE

@allo-

This comment has been minimized.

Copy link
Owner Author

allo- commented Oct 2, 2017

Maybe mozilla can be convinced to a "RFP overrides settings" option? Either another integer value or per pref, like dom.netinfo.enabled.rfp_overrides=true or something like that?

Tor though, only has to worry about a single release - and so do we in a sense - your profile maker has to deal with the entire spectrum

Yes and I think it only scratches on the surface. Still it tries to get some of the main points. When I imagine people browsing with year old cookies, I suddenly realize how much protection a single setting can give you.

@Thorin-Oakenpants

This comment has been minimized.

Copy link

Thorin-Oakenpants commented Oct 2, 2017

No way would they create loads of override prefs - it doesn't make sense code wise either. The original intent of the RFP pref was to flip the prefs to the desired setting - but this was problematic for a number of reasons such as remembering the previous state etc, and permissions restrictions within firefox code etc.

If they were super serious, the code would bypass any modified value of the corresponding pref - so on mobile if a user had dom.netinfo.enabled=false then it should ignore that and use the default value in omni.ja (it is default true on mobile) and thus the RFP behaves.

  • i.e all RFP mobile users would return "unknown", but because this sort of enforcement is fully coded, some mobile users could return undefined

Trust me, there is a lot more to come with these sorts of inconsistent results where RFP and prefs can cause different fingerprints. Its not the magic bullet you think it is, not yet - so far most of it can already be covered in other ways, but some of it has been good + new, such as spoofing UTC and covering MediaError.messages etc (stuff we have no pref or means to handle).

It a lot of work. Most people are FP'able anyway, and we're not even talking about stuff like audio FP, and sooo many more things not really covered - CA fingerprinting, cipher FP'ing, lots of things. I would leave the pref in on its own, and just add a disclaimer that prefs marked with [symbol] in your profilemaker can conflict at worst, or be redundant at best with RFP

Mock Up

  • privacy.resistFingerprinting
    • enable Resist Fingerprinting
    • other prefs marked can conflict with the patches this provides
  • dom.netinfo.enabled
    disable leaking network information ¶ covered by RFP in FF56
  • dom.w3c_touch_events.enabled
    disable touch events (0=disabled, 1=enabled, 2=autodetect) ¶ covered by RFP in FF57

^^ this way its easy for the end user, who knows what FF version they are on, which ones to add/leave. Just put the RFP option near the start

@allo-

This comment has been minimized.

Copy link
Owner Author

allo- commented Oct 2, 2017

Most people are FP'able anyway
In the end I see the issue a bit more complicated. Panopticlick tells me always I am unique.
But it tells me always I am unique.

The fingerprinting we need to fear is the stable fingerprint, not the unique one. Install one font and lose your font-fingerprint. Now reduce it to a few bit linux vs. windows fonts, install one font and do not lose it.
That are the important points, what can be used over a longer time will be used, not the most unstable things, just because they convey a few bits more.

I would leave the pref in on its own, and just add a disclaimer that prefs marked with [symbol] in your profilemaker can conflict at worst, or be redundant at best with RFP
Sounds like a good idea. But in the end I do not know for most settings, which firefox versions introduced them, possible for some not even when they are no longer needed. This is hard to keep up with and currently I have a lot less time then I would like to have for it.

From the vast amount of input I think the ghacks things are what I want to process next, because it comes with some more documentation than most. If you're still searching for more unsorted input, look in the wiki of this project, there are quite a few collections linked.

@Thorin-Oakenpants

This comment has been minimized.

Copy link

Thorin-Oakenpants commented Oct 2, 2017

Panopticlick is a PoS (piece of shit), as are ALL those who attempt to tell you how unique you are. Datasets are skewed (in so many ways - they are NOT real world TODAY), datasets are not all current (eg panopticlick is years worth of user agents and browser version numbers), datasets are not big enough ... and in the case of Panopticlick, you cannot block canvas or the script fails and never finishes, so instead you spoof .. and because you spoof every time, then every time that value is unqiue, so every time you do the test, you are unique - that's how flawed that test is - also people are idiots and don't understand fingerprinting

You cannot beat FP'ing - the best you can do is be consistent within a small subset (eg FF RFP users) and you beat 95% of it by controlling JS and XSS - and the rest thru OpSec. I've been on this ant-FPing train for 6 years - I know lots, I think I have most of it worked out - and it's hard mate, really hard. The FP is techincal but totally doable even today - when paired with OpSec which is the hard part, but also doable. You can;t teach OpSec in my opinion :)

Resources: been on this train for years mate - we've already mapped the Firefox genome

Fonts: already covered. People are lazy, they want to use fonts. I've used browser.display.use_document_fonts" = 0 for 3+ years and never missed anything. RFP is almost done with covering this as well, by bundling fonts with FF via Kinto, and setting the font.system.whitelist pref they created back in FF52. Just an example of another clash between RFP & existing prefs.

Feel free to ransack our genome project :)

@allo-

This comment has been minimized.

Copy link
Owner Author

allo- commented Oct 2, 2017

They have a point about bits of information, but they present it in the wrong way.
For fonts ... the problem is bigger than disabling websites to choose their fonts, as you may think this setting is 1 bit, but actually it would only be if half the people switch it off. Many other settings have the same problem.
And the seemingly changing properties can be dangerous. You do not need things like big learning, which are already used to optimize err webanalysis, with simple statistics you can significantly reduce the noise. So you may see 100 unique font combinations (to use a simple example again), but with some statistics you see that there are 10 fonts (present or absent), which are your actual fingerprint. With enough log-data you can find these factors and use them. So you either need full random fuzzing or zero information, just "good enough" isn't really.

Resources: been on this train for years mate - we've already mapped the Firefox genome

A lot of work ...

@allo- allo- referenced this issue Nov 19, 2017

Open

Mozilla buildID #86

@allo-

This comment has been minimized.

Copy link
Owner Author

allo- commented Dec 11, 2017

For the useragent, RFP overrides general.useragent.override currently using Firefox 50, not the other way round.

This is no good thing, as Firefox 50 now isn't very common anymore. I do not get why they don't set this to the current ESR or the previous ESR if the current one is too recent.

@Thorin-Oakenpants

This comment has been minimized.

Copy link

Thorin-Oakenpants commented Dec 11, 2017

@allo-
in 57 the rounding was to round down to the nearest multiple of ten
in 58+ the rounding is round down to match ESR (which makes more sense, and better for extension compat, site compat)

As for the version number used, it does not really matter - as long as the SUBSET of RFP users are all the same. They could all be using v99 Toaster for all anyone cares, but then that would definitely put them in the RFP subset with just one bit of entropy/information, and is a bit silly (site breakage etc). It's not about trying to make RFP look like the rest of the FF users, it about making RFP users all the same within their own group.

One day, soon, when RFP is used with Private Windows, that subset will grow. When RFP gets a checkbox in the preferences UI, that subset will grow. I can't wait :) Meanwhile, as has always been the case, control JS/XSS/3rd parties etc as much as possible to limit possible client-side FP'ing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.