Closed
Bug 1333651
Opened 8 years ago
Closed 7 years ago
Spoofing Navigator API when resisting fingerprinting is enabled
Categories
(Core :: DOM: Security, defect, P1)
Core
DOM: Security
Tracking
()
RESOLVED
FIXED
mozilla56
Tracking | Status | |
---|---|---|
firefox56 | --- | fixed |
People
(Reporter: timhuang, Assigned: timhuang)
References
(Blocks 1 open bug)
Details
(Whiteboard: [tor][fingerprinting][domsecurity-backlog1][fp:m2])
Attachments
(3 files)
The navigator API reveals certain information about the user's browser, like its buildId. So we should spoof these values of navigator API to disable fingerprinting through these values when resisting fingerprinting is enabled.
Which values should we spoof? IMHO: 1 User-Agent header value should be replaced with "webbrowser;<html standard version>;<css standard version>;<ECMAScript standard version>" 2 Permissions for retrieving sensitive information about environment should be introduced. I mean that in order to get something meaningful from that variables the app should request a permission, a user can either grant ut, providing true info, or refuse (providing user-defined fake info, an app must see it as "granted" in both cases.)
Updated•8 years ago
|
Priority: -- → P2
Updated•8 years ago
|
Whiteboard: [tor][fingerprinting] → [tor][fingerprinting][domsecurity-backlog1]
Assignee | ||
Updated•8 years ago
|
Assignee: nobody → tihuang
Updated•8 years ago
|
Whiteboard: [tor][fingerprinting][domsecurity-backlog1] → [tor][fingerprinting][domsecurity-backlog1][fp:m1]
Assignee | ||
Updated•8 years ago
|
Status: NEW → ASSIGNED
Assignee | ||
Comment 2•7 years ago
|
||
The navigator is an ideal place for browser fingerprinting, so spoof and disable some features of navigator object would be beneficial for fingerprinting resistance. Following is what I am going to do with navigator object when 'privacy.resistFingerprinting' is true. * Spoofing - navigator.appName - navigator.appVersion - navigator.platform - navigator.userAgent - navigator.mimeTypes (already done) - navigator.plugins (already done) - navigator.oscpu - navigator.buildID * Disabling - navigator.geolocation - navigator.connection - navigator.mediaDevices
Assignee | ||
Comment 3•7 years ago
|
||
Following are reasons why we want to disable geo location API, network information API and media devices API when 'privacy.resistFingerprinting' is true. a) For geo location API, although, it requires users to grant its permission to access this API. But, I think we still need to disable this API becasue of two reasons. For the one hand, one user could grant this permission before 'privacy.resistFingerprinting' has been turned on, so this API can still be accessed in this case. On the other hand, users may incautiously grant this permission while 'privacy.resistFingerprinting' is on. Therefore, we'd better to disable this. b) For network information API, it will reveal your connection type which is a fingerprintable vector. c) For media devices, this can be used to enumerate a user's media devices. We should not reveal users' hardware settings when fingerprinting resistance is on.
Assignee | ||
Comment 4•7 years ago
|
||
Making this depends on Bug 1369303 since patches here need to check 'privacy.resistFingerprinting' in worker thread and we will expose this pref to the worker thread in Bug 1369303.
Depends on: 1369303
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 9•7 years ago
|
||
(In reply to Tim Huang[:timhuang] from comment #3) > c) For media devices, this can be used to enumerate a user's media devices. > We should not reveal users' hardware settings when fingerprinting resistance > is on. Are you trying to be comprehensive about this? For example, have you looked at navigator.hardwareConcurrency? There is also a WebGL API that reveals your graphics card driver (I don't remember what it's called off the top of my head). There's probably other similar examples if you looked hard enough...
Comment 10•7 years ago
|
||
mozreview-review |
Comment on attachment 8876029 [details] Bug 1333651 - Part 1: Spoofing the User-Agent header when 'privacy.resistFingerprinting' is true. https://reviewboard.mozilla.org/r/147474/#review151924 ::: netwerk/protocol/http/nsHttpHandler.cpp:797 (Diff revision 1) > if (mUserAgentOverride) { > LOG(("using general.useragent.override : %s\n", mUserAgentOverride.get())); > return mUserAgentOverride; > } > > + if (nsContentUtils::ShouldResistFingerprinting() && This seems wrong, FWIW perhaps, depending on what you intended it to do. Right now with your patch if Firefox decides to override the UA string for a site, that would override the Tor Browser's fingerprinting resistance. It seems like things should be the other way around?
Comment 11•7 years ago
|
||
(In reply to :Ehsan Akhgari (needinfo please, extremely long backlog) from comment #9) > (In reply to Tim Huang[:timhuang] from comment #3) > > c) For media devices, this can be used to enumerate a user's media devices. > > We should not reveal users' hardware settings when fingerprinting resistance > > is on. > > Are you trying to be comprehensive about this? For example, have you looked > at navigator.hardwareConcurrency? There is also a WebGL API that reveals > your graphics card driver (I don't remember what it's called off the top of > my head). There's probably other similar examples if you looked hard > enough... We have certainly tried to be comprehensive! =) hardwareConcurreny: Bug 1360039 WebGL: Bug 1217290 If there's any others that come to mind, and you don't see it at https://bugzilla.mozilla.org/showdependencytree.cgi?id=1329996&hide_resolved=1 please let know (or even if you do see it, feel free to leave a drive-by comment to confirm we are addressing what you're thinking of.)
Comment 12•7 years ago
|
||
mozreview-review |
Comment on attachment 8876030 [details] Bug 1333651 - Part 2: Spoofing Navigator object when 'privacy.resistFingerprinting' is true. https://reviewboard.mozilla.org/r/147476/#review151928 ::: dom/base/Navigator.cpp:469 (Diff revision 1) > Navigator::GetOscpu(nsAString& aOSCPU, CallerType aCallerType, > ErrorResult& aRv) const > { > if (aCallerType != CallerType::System) { > + // If fingerprinting resistance is on, we will spoof this value to 'Windows NT 6.1'. > + if (nsContentUtils::ShouldResistFingerprinting()) { This function isn't thread-safe. ::: dom/base/Navigator.cpp:470 (Diff revision 1) > ErrorResult& aRv) const > { > if (aCallerType != CallerType::System) { > + // If fingerprinting resistance is on, we will spoof this value to 'Windows NT 6.1'. > + if (nsContentUtils::ShouldResistFingerprinting()) { > + aOSCPU.AssignLiteral("Windows NT 6.1"); Please don't hard-code strings like this in the source code. Please use some #defines in the beginning of the file, preferrably all in the same place so that it's clear what the Navigator object returns by skimming the code quickly when fingerprinting resistence is turned on without having to examine each one of these functions. ::: dom/base/Navigator.cpp:650 (Diff revision 1) > ErrorResult& aRv) const > { > if (aCallerType != CallerType::System) { > + // If fingerprinting resistance is on, we will spoof this value to '20100101'. > + if (nsContentUtils::ShouldResistFingerprinting()) { > + aBuildID.AssignLiteral("20100101"); This is repeated in GetProductSub() as well. Please use the same macro in both functions. Bonus points if you move all of these macros to a helper header and also use them in nsHttpHandler::Init()! ::: dom/base/Navigator.cpp:1760 (Diff revision 1) > +bool > +Navigator::HasGeoLocationSupport(JSContext* /* unused */, > + JSObject* /* unused */) > +{ > + return !nsContentUtils::ShouldResistFingerprinting() && > + Preferences::GetBool("geo.enabled", true); Do you have any reason to believe that doing this is Web compatible? I don't think it would be. I think the way to disable this is similar to bug 1072859 where we disabled this API for non-secure origins, i.e. by throwing an exception when the API entry points are called as opposed to hiding Navigator.geolocation. I suggest breaking this part into a separate bug. (In the future, please try to keep changes like this as separate patches per each logical change, for example make a separate patch per each API you are disabling, to avoid making things difficult when one of the changes are wrong...)
Attachment #8876030 -
Flags: review?(ehsan) → review-
Comment 13•7 years ago
|
||
mozreview-review |
Comment on attachment 8876031 [details] Bug 1333651 - Part 3: Add a test case to verify that Navigator object has been spoofed/disabled correctly when 'privacy.resistFingerprinting' is true. https://reviewboard.mozilla.org/r/147478/#review151938 This needs to be changed as per my review on part 2.
Attachment #8876031 -
Flags: review?(ehsan)
Comment 14•7 years ago
|
||
(In reply to Tom Ritter [:tjr] from comment #11) > (In reply to :Ehsan Akhgari (needinfo please, extremely long backlog) from > comment #9) > > (In reply to Tim Huang[:timhuang] from comment #3) > > > c) For media devices, this can be used to enumerate a user's media devices. > > > We should not reveal users' hardware settings when fingerprinting resistance > > > is on. > > > > Are you trying to be comprehensive about this? For example, have you looked > > at navigator.hardwareConcurrency? There is also a WebGL API that reveals > > your graphics card driver (I don't remember what it's called off the top of > > my head). There's probably other similar examples if you looked hard > > enough... > > We have certainly tried to be comprehensive! =) > > hardwareConcurreny: Bug 1360039 > WebGL: Bug 1217290 Oh great! > If there's any others that come to mind, and you don't see it at > https://bugzilla.mozilla.org/showdependencytree. > cgi?id=1329996&hide_resolved=1 please let know (or even if you do see it, > feel free to leave a drive-by comment to confirm we are addressing what > you're thinking of.) I'll try to think of more examples as drive-by's, but to be honest I don't have a lot of cycles these days to devote to thinking about this systematically... I suggest doing an audit of dom/webidl at some point when we're about to get to a finishing point of this project. I have been following things from very far away so I have no idea how close we are, but no need to panic unless if we're about to wrap up. :-)
Comment 15•7 years ago
|
||
(You should feel free to reach out to other DOM peers about this general issue who may have more free time these days if you need help with a more broad audit, btw.)
Assignee | ||
Comment 16•7 years ago
|
||
(In reply to :Ehsan Akhgari (needinfo please, extremely long backlog) from comment #10) > Comment on attachment 8876029 [details] > Bug 1333651 - Part 1: Spoofing the User-Agent header when > 'privacy.resistFingerprinting' is true. > > This seems wrong, FWIW perhaps, depending on what you intended it to do. > Right now with your patch if Firefox decides to override the UA string for a > site, that would override the Tor Browser's fingerprinting resistance. It > seems like things should be the other way around? Thanks for pointing this out. Yes, you are right, this should be put before userAgentOverride. I will fix this at next push.
Assignee | ||
Comment 17•7 years ago
|
||
(In reply to :Ehsan Akhgari (needinfo please, extremely long backlog) from comment #12) > Comment on attachment 8876030 [details] > Bug 1333651 - Part 2: Spoofing Navigator object when > 'privacy.resistFingerprinting' is true. > > https://reviewboard.mozilla.org/r/147476/#review151928 > > ::: dom/base/Navigator.cpp:469 > (Diff revision 1) > > Navigator::GetOscpu(nsAString& aOSCPU, CallerType aCallerType, > > ErrorResult& aRv) const > > { > > if (aCallerType != CallerType::System) { > > + // If fingerprinting resistance is on, we will spoof this value to 'Windows NT 6.1'. > > + if (nsContentUtils::ShouldResistFingerprinting()) { > > This function isn't thread-safe. This function has been turned into thread-safe in Bug 1217238. > ::: dom/base/Navigator.cpp:1760 > (Diff revision 1) > > +bool > > +Navigator::HasGeoLocationSupport(JSContext* /* unused */, > > + JSObject* /* unused */) > > +{ > > + return !nsContentUtils::ShouldResistFingerprinting() && > > + Preferences::GetBool("geo.enabled", true); > > Do you have any reason to believe that doing this is Web compatible? I > don't think it would be. I think the way to disable this is similar to bug > 1072859 where we disabled this API for non-secure origins, i.e. by throwing > an exception when the API entry points are called as opposed to hiding > Navigator.geolocation. I suggest breaking this part into a separate bug. > After thinking about this, I think we should try our best to neutralize the threat of fingerprinting without breaking the web compatibility and treat disabling them as a last resort. > (In the future, please try to keep changes like this as separate patches per > each logical change, for example make a separate patch per each API you are > disabling, to avoid making things difficult when one of the changes are > wrong...) I will open separate bugs for geo location, network information and media devices.
Updated•7 years ago
|
Whiteboard: [tor][fingerprinting][domsecurity-backlog1][fp:m1] → [tor][fingerprinting][domsecurity-backlog1][fp:m2]
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 21•7 years ago
|
||
mozreview-review |
Comment on attachment 8876030 [details] Bug 1333651 - Part 2: Spoofing Navigator object when 'privacy.resistFingerprinting' is true. https://reviewboard.mozilla.org/r/147476/#review152516 ::: commit-message-3f4a4:4 (Diff revision 2) > +Bug 1333651 - Part 2: Spoofing Navigator object when 'privacy.resistFingerprinting' is true. r?Ehsan,arthuredelstein > + > +This patch makes navigator object to return spoofed value for fields have fingerprintable > +concerns. This changes the worker navigatoras well. Nit: s/navigartoras/navigator as/ ::: toolkit/components/resistfingerprinting/nsRFPService.h:14 (Diff revision 2) > #include "mozilla/Atomics.h" > #include "nsIObserver.h" > > #include "nsString.h" > > +// Defines regarding spoofed values of Navigator object. Please extend this comment to also say that these are returned when the fingerprinting resisting mode is activated.
Attachment #8876030 -
Flags: review?(ehsan) → review+
Comment 22•7 years ago
|
||
mozreview-review |
Comment on attachment 8876031 [details] Bug 1333651 - Part 3: Add a test case to verify that Navigator object has been spoofed/disabled correctly when 'privacy.resistFingerprinting' is true. https://reviewboard.mozilla.org/r/147478/#review152518
Attachment #8876031 -
Flags: review?(ehsan) → review+
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 26•7 years ago
|
||
mozreview-review |
Comment on attachment 8876029 [details] Bug 1333651 - Part 1: Spoofing the User-Agent header when 'privacy.resistFingerprinting' is true. https://reviewboard.mozilla.org/r/147474/#review153150
Attachment #8876029 -
Flags: review?(arthuredelstein) → review+
Comment 27•7 years ago
|
||
mozreview-review |
Comment on attachment 8876031 [details] Bug 1333651 - Part 3: Add a test case to verify that Navigator object has been spoofed/disabled correctly when 'privacy.resistFingerprinting' is true. https://reviewboard.mozilla.org/r/147478/#review153160
Attachment #8876031 -
Flags: review?(arthuredelstein) → review+
Comment 28•7 years ago
|
||
mozreview-review |
Comment on attachment 8876030 [details] Bug 1333651 - Part 2: Spoofing Navigator object when 'privacy.resistFingerprinting' is true. https://reviewboard.mozilla.org/r/147476/#review153164
Attachment #8876030 -
Flags: review?(arthuredelstein) → review+
Comment 29•7 years ago
|
||
mozreview-review |
Comment on attachment 8876029 [details] Bug 1333651 - Part 1: Spoofing the User-Agent header when 'privacy.resistFingerprinting' is true. https://reviewboard.mozilla.org/r/147474/#review154508 can you justify why we need a fourth way to set the UA? (default, general.useragent.override, and the per-domain override) Why does the existing override pref not do the job?
Attachment #8876029 -
Flags: review?(mcmanus)
Assignee | ||
Comment 30•7 years ago
|
||
(In reply to Patrick McManus [:mcmanus] from comment #29) > can you justify why we need a fourth way to set the UA? (default, > general.useragent.override, and the per-domain override) Why does the > existing override pref not do the job? The main idea is that we want to put all anti-fingerprinting features behind one pref, 'privacy.resistFingerprinting'. The UA spoofing is one of them. At first place, we did want to use existing pref, general.useragent.override, to do the job and treat the 'privacy.resistFingerprinting' as a meta pref. So, when a user flip 'privacy.resistFingerprinting', it will automatically flip other prefs, like 'general.useragent.override'. However, it turned out to be not a good solution since we need to handle store and restore of user setting prefs and it will have lots of ramifications that need to be considered [1]. So, right now, we think a better approach is that patching fingerprintiable features directly and not relies on the pref system. There are two benefits of doing this. 1. When 'privacy.resistFingerprinting' is true, the fingerprinting resistance is enforced regardless of other prefs value. This behavior is much simpler for users and developers to understand. 2. Building anti-fingerprinting feature directly into gecko is concrete than building it on top of pref system since prefs could be removed or changed. So, go back to the UA spoofing, we need a way other than the existing 'general.useragent.override' solution to do the job. Does this answer your concern? :) [1] Bug 1333933 comment 17
Flags: needinfo?(mcmanus)
Comment 31•7 years ago
|
||
mozreview-review |
Comment on attachment 8876029 [details] Bug 1333651 - Part 1: Spoofing the User-Agent header when 'privacy.resistFingerprinting' is true. https://reviewboard.mozilla.org/r/147474/#review154986 let's do it
Attachment #8876029 -
Flags: review+
Updated•7 years ago
|
Flags: needinfo?(mcmanus)
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Assignee | ||
Comment 36•7 years ago
|
||
Try looks good. https://treeherder.mozilla.org/#/jobs?repo=try&revision=44bb575fa3fd
Keywords: checkin-needed
Comment 37•7 years ago
|
||
Pushed by cbook@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/a9c101b46ab6 Part 1: Spoofing the User-Agent header when 'privacy.resistFingerprinting' is true. r=arthuredelstein,mcmanus https://hg.mozilla.org/integration/autoland/rev/76040a8fabaa Part 2: Spoofing Navigator object when 'privacy.resistFingerprinting' is true. r=arthuredelstein,Ehsan https://hg.mozilla.org/integration/autoland/rev/5131e38858f9 Part 3: Add a test case to verify that Navigator object has been spoofed/disabled correctly when 'privacy.resistFingerprinting' is true. r=arthuredelstein,Ehsan
Keywords: checkin-needed
Comment 38•7 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/a9c101b46ab6 https://hg.mozilla.org/mozilla-central/rev/76040a8fabaa https://hg.mozilla.org/mozilla-central/rev/5131e38858f9
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
status-firefox56:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla56
Comment 39•7 years ago
|
||
Verified successfully that the User-Agent header is correctly spoofed. Verified on Mac Os 10.12.6 with Nightly 58.0a1 (2017-10-23) (64-bit) Verification steps: 1. Start the browser, open a new tab and go to https://browserprint.info/test 2. Open a new tab and go to about:config, then change the privacy.resistFingerprinting to true 3. Open a new tab and go to https://browserprint.info/test Expected results: Compare the results from step 1 and 3. In step 1, user-agent should show correct information about the current system. In step 3, user-agent should show spoofed information Actual results: From step 1: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:58.0) Gecko/20100101 Firefox/58.0 From step 3: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0
You need to log in
before you can comment on or make changes to this bug.
Description
•