Opened 4 years ago

Closed 4 years ago

Last modified 3 years ago

#17207 closed defect (fixed)

Testing navigator.mimeTypes for known names can reveal info and increase fingerprinting risk

Reported by: TemporaryNick Owned by: arthuredelstein
Priority: High Milestone:
Component: Applications/Tor Browser Version:
Severity: Major Keywords: tbb-fingerprinting, TorBrowserTeam201510R
Cc: brade, mcs Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

I gathered a list of MIME Types from IANA and other sources. Then explicitly used each type to check if navigator.mimeTypes[type] === undefined. I found that I could detect quite a few MIME Types in this way. Including some types that are related to specific application programs and/or peripheral devices.

I maxed the security slider, which disabled Javascript by default and broke the test script. However, after I whitelisted the test script I was able to achieve the same results.

I was testing Tor Browser 5.0.3 for Windows.

Child Tickets

Attachments (2)

MimeTypeDetector.html (44.0 KB) - added by TemporaryNick 4 years ago.
Demonstrates detection method using a subset of MIME Types
MimeTypeDetectorTBB503.html (44.0 KB) - added by teor 4 years ago.
MIME Type Detector Modified to work with TBB 5.0.3

Download all attachments as: .zip

Change History (23)

comment:1 Changed 4 years ago by teor

Can you please attach the script you used?

comment:2 Changed 4 years ago by huseby

Or better yet, can you implement it as a mochitest unit test and submit a patch? I think it would be really good for me to start uplifting all of these unit tests to mainline. I figure out a way to make them NOT run by default, but it would be great to have them for testing purposes as I re-factor and uplift other patches.

Changed 4 years ago by TemporaryNick

Attachment: MimeTypeDetector.html added

Demonstrates detection method using a subset of MIME Types

comment:3 Changed 4 years ago by TemporaryNick

I uploaded an example, which tests only the application types listed by IANA. There are other types than can be checked and there are an unknown number of types that aren't registered with IANA.

I think the issue is that when you check for a MIME Type in this way, the browser checks with the OS to see whether the MIME Type has been registered. Which MIME Types are registered depends on which application software and/or drivers the user chose to install. My test results were different on different Windows systems. I was, however, testing with a more comprehensive list than that shown in the demonstration.

I think the place to start may be nsMimeTypeArray.cpp, and what happens when you check for a named item. I found someone talking about this type of issue and approaching it via GreaseMonkey script. They mentioned that websites frequently test for some specific MIME Types, so simply blocking named lookups may not be practical.

I don't know enough to tackle this issue.

comment:4 Changed 4 years ago by gk

Keywords: tbb-fingerprinting added; fingerprinting removed
Status: newneeds_information

I just tested with an en-US 5.0.3 on Windows 7 and all I get is

navigator.mimeTypes.length not > 0

Did you try with a fresh, unmodified Tor Browser 5.0.3? What Windows version did you use? How can I reproduce your problem if it still persists?

comment:5 Changed 4 years ago by teor

In Tor Browser 5.0.3 on OS X 10.10.5, I can't retrieve the length navigator.mimeTypes.length or list of members navigator.mimeTypes.

But I can query for a member (as TemporaryNick describes).

Can you try the attached script with if (navigator.mimeTypes.length > 0) { and the corresponding brace commented out?

Changed 4 years ago by teor

Attachment: MimeTypeDetectorTBB503.html added

MIME Type Detector Modified to work with TBB 5.0.3

comment:6 Changed 4 years ago by teor

I attached a modified version that works in Tor Browser 5.0.3 on OS X 10.10.5.

It discovers my Microsoft Office installation. It also discovers my Wireshark installation.

This looks like a fingerprint to me, but I don't have multiple machines to test it on, so I can't be sure.

comment:7 Changed 4 years ago by gk

Keywords: TorBrowserTeam201510 added
Owner: changed from tbb-team to arthuredelstein
Priority: normalmajor
Status: needs_informationassigned

Good stuff! I thought we already had a defense against this but I could not find anything so far. Arthur: do you have some spare cycles to look at this in October? I fear all the other TBB people are busy with deadline work...

comment:8 Changed 4 years ago by mcs

Cc: brade mcs added

comment:9 in reply to:  7 ; Changed 4 years ago by arthuredelstein

Replying to gk:

Good stuff! I thought we already had a defense against this but I could not find anything so far.

It's interesting that navigator.mimeTypes.length == 0. So one would have thought it didn't have any members.

Arthur: do you have some spare cycles to look at this in October? I fear all the other TBB people are busy with deadline work...

Yes -- I'll try to look at this soon.

comment:10 in reply to:  9 ; Changed 4 years ago by teor

Severity: Blocker

Replying to arthuredelstein:

Replying to gk:

Good stuff! I thought we already had a defense against this but I could not find anything so far.

It's interesting that navigator.mimeTypes.length == 0. So one would have thought it didn't have any members.

It seems that a partial anti-enumeration design is in place, but only against positional iteration. (As well as setting navigator.mimeTypes.length to 0, all indexes of the form navigator.mimeTypes[0] return undefined.)

But that doesn't stop lookups using an external list of MIME type names.

comment:11 Changed 4 years ago by teor

Severity: BlockerMajor

(The Severity was set to the default due to dgoulet's Trac changes. I set it to Major to match the previous Priority field.)

comment:12 in reply to:  10 Changed 4 years ago by arthuredelstein

Replying to teor:

Replying to arthuredelstein:

Replying to gk:

Good stuff! I thought we already had a defense against this but I could not find anything so far.

It's interesting that navigator.mimeTypes.length == 0. So one would have thought it didn't have any members.

It seems that a partial anti-enumeration design is in place, but only against positional iteration. (As well as setting navigator.mimeTypes.length to 0, all indexes of the form navigator.mimeTypes[0] return undefined.)

Unfortunately, the anti-enumeration protection which was introduced in this bug:
https://bugzilla.mozilla.org/show_bug.cgi?id=757726
was removed in Firefox 41:
https://bugzilla.mozilla.org/show_bug.cgi?id=1169945

comment:13 Changed 4 years ago by arthuredelstein

Keywords: TorBrowserTeam201510R added; TorBrowserTeam201510 removed
Status: assignedneeds_review

It turns out that the mimeTypes list in Firefox comes from two sources: (1) plugins and (2) applications installed on the system. I considered writing a fixed spoof list of mimeTypes, but it was not clear to me which mimeTypes, if any, should be included in such a list.

At this point, Tor Browser strongly discourages the use of plugins (and makes them click-to-play). So it probably makes sense to make the navigator.plugins object appear to be empty to content pages and not show any plugin-associated mimeTypes. This might in principle break a site that requires Flash, but as we (and Mozilla) are discouraging the use of Flash, I'm inclined not to spoof the presence of a "Flash" plugin. Especially as spoofing the presence of Flash might prevent a JS fallback on some sites.

For applications, I think it is reasonable to force websites to assume that any file will be downloaded rather than opened by a helper app.

So, given these conclusions about plugins and applications, I decided to make navigator.mimeTypes appear empty to content pages as well. But I'm open to further discussion.

I bound this behavior to the "privacy.resistFingerprinting" pref, which will hopefully make Mozilla more amenable to accepting it.

The following branch has two commits for review: the implementation and a regression test:

https://github.com/arthuredelstein/tor-browser/commits/17207+1

comment:14 Changed 4 years ago by gk

Status: needs_reviewneeds_revision

First round of comments:

1) You probably want to do something like #include "nsContentUtils.h" in nsPluginArray.cpp, too (I wonder how you got it compiled without actually).

2) I don't understand

  // TODO: The following line should be active in Firefox 45
+  // isnot(navigator.mimeTypes.length, 0, "navigator.mimeTypes array should be 0");

.

What does it mean? We don't need that test yet? If so, why not? Or does it mean we can't run that test right now because XXX would break it? If so what fixes this (Do you have a bug number?)? And does it mean we are save for now with respect to leaking the length of the supported MIME types? If I am guessing right, the answer lies in https://bugzilla.mozilla.org/show_bug.cgi?id=757726 which got resolved as WON'TFIX. If that is true could you add a hint about that in the test explaining what is going on?

3) s/prmoise/promise/ in the test

comment:15 in reply to:  14 Changed 4 years ago by arthuredelstein

Status: needs_revisionneeds_review

Replying to gk:

First round of comments:

1) You probably want to do something like #include "nsContentUtils.h" in nsPluginArray.cpp, too (I wonder how you got it compiled without actually).

I wonder that too. Apparently it is included in a header file somewhere. I've added #include "nsContentUtils.h" in nsPluginArray.cpp for clarity.

2) I don't understand

  // TODO: The following line should be active in Firefox 45
+  // isnot(navigator.mimeTypes.length, 0, "navigator.mimeTypes array should be 0");

.

What does it mean? We don't need that test yet? If so, why not? Or does it mean we can't run that test right now because XXX would break it? If so what fixes this (Do you have a bug number?)? And does it mean we are save for now with respect to leaking the length of the supported MIME types? If I am guessing right, the answer lies in https://bugzilla.mozilla.org/show_bug.cgi?id=757726 which got resolved as WON'TFIX. If that is true could you add a hint about that in the test explaining what is going on?

3) s/prmoise/promise/ in the test

Thanks. I've fixed these things:
https://github.com/arthuredelstein/tor-browser/commits/17207+2

comment:16 Changed 4 years ago by gk

mcs/brade: if you have some capacities left and would have a look at this one, too, that would be grand. We might be able to include that one into the alpha as well then.

comment:17 Changed 4 years ago by mcs

Kathy is not here at the moment and I actually have to leave soon too... but I took a quick look and the patch and tests look OK to me.

comment:18 Changed 4 years ago by gk

This looks okay to me and I merged cherry-picked the commits onto tor-browser-38.3.0esr-5.5-2. One question: Is there any reason why you did not add ||ResistFingerprinting() to any !AllowPlugins()? I guess only those where you added them are fingerprinting relevant? I wonder if that is going to lead into some confusion though: there may be things doable with plugins if you have fingerprinting defenses enabled (and are allowing plugins) and other things only if you have them disabled. Or are there no such things? I know there are a bunch of users that (need to?) enable Flash but maybe we just don't care about them too much here.

comment:19 Changed 4 years ago by gk

Resolution: fixed
Status: needs_reviewclosed

Commit 5ea30524fbf92005f236756646beb77684cd2008 and 5578785b6c12ff62b5a2cdcc3d2f5c9762af6c5c are the ones in question.

comment:20 in reply to:  18 Changed 4 years ago by arthuredelstein

Replying to gk:

This looks okay to me and I merged cherry-picked the commits onto tor-browser-38.3.0esr-5.5-2. One question: Is there any reason why you did not add ||ResistFingerprinting() to any !AllowPlugins()? I guess only those where you added them are fingerprinting relevant? I wonder if that is going to lead into some confusion though: there may be things doable with plugins if you have fingerprinting defenses enabled (and are allowing plugins) and other things only if you have them disabled. Or are there no such things? I know there are a bunch of users that (need to?) enable Flash but maybe we just don't care about them too much here.

I only added ||ResistFingerprinting() to places where information is exposed through the content web APIs. I believe the other functions are only called by Chrome code, so ResistFingerprinting() would always return false.

I think the scope of this ticket is not to disable plugins, but merely to prevent their detection through navigator.plugins. It is in principle still possible to detect plugins by including several of them in a page -- but if we enforce click-to-play, then this is not really a practical attack, I think.

comment:21 Changed 3 years ago by bugzilla

Corresponding Mozilla work: https://www.fxsitecompat.com/en-CA/docs/2016/navigator-plugins-and-mimetypes-will-be-unenumerable/
Mozilla made an exception for Flash because of compatibility problems.

Last edited 3 years ago by bugzilla (previous) (diff)
Note: See TracTickets for help on using tickets.