Closed Bug 903959 Opened 11 years ago Closed 7 years ago

custom resource://foo/ allows fingerprinting addons

Categories

(Core :: Security, defect)

defect
Not set
major

Tracking

()

RESOLVED DUPLICATE of bug 863246

People

(Reporter: janekptacijarabaci, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: privacy, sec-low, Whiteboard: [fingerprinting])

Severity: normal → major
OS: Windows 7 → All
Hardware: x86_64 → All
Status: UNCONFIRMED → NEW
Ever confirmed: true
When we locked down access to chrome:// URIs based on the registry, we left resource:// open for things flagges as ALLOW_CHROME (e.g. scripts).

Is there a reason to allow this nowadays?
Component: General → Security
Flags: needinfo?(dveditz)
This issue is not limited to <SCRIPT> tags -- if you're worried about fingerprintability then exposing a custom URL anywhere is a problem. This was true back in bug 292789 as well, the bug summary says SCRIPT but the fix applied to content in general.

We allowed accessibility for resource:/// which pointed at the installed on-disk resources that came with Firefox. I don't know if we supported alternate resource aliases at the time, but I'm sure add-ons weren't using them and that we didn't support resource aliasing in chrome.manifest (which didn't exist).

When we introduced resource into chrome.manifest we should have added the option contentaccessible=yes mechanism at the same time: let add-ons opt-in to fingerprintability just as we do with chrome content. Unfortunately anything we do may have compatibility problems: searching addon source I find 810 chrome.manifest files that define custom resource:// locations. One reason for so many is because it's used by JetPack addons so I'm somewhat hopeful that most of those don't need to reference these from content.

Alternatives that come to mind:
a) hide resource://foo/ unless chrome.manifest has contentaccessible=yes
b) hide resource://foo/ if chrome.manifest says contentaccessible=no
c) only expose resource://foo/ if the chrome.manifest has put contentaccessible=yes
   on the corresponding "content foo" line.

Between the first two a) is both safer and consistent with chrome handling but more likely to break some addons. b) won't cause any breakage (because addon authors can fix it when they opt-in) but in practice isn't going to protect many addons from fingerprintability. Both may cause backwards compatibility problems for authors who need their addons to work in both old and new versions of Firefox. We'll have to investigate what the chrome.manifest parser does with unexpected tokens on the end of a resource line.

c) is a bit random. Inspired by the fact that visibility of skin and locales files are all controlled by the content definition, this would avoid the backwards compatibility trap if the old parser will choke on a new term (not yet determined). In practice, though, some add-ons don't use the same name for their resource: and content, and some addons have multiple resource definitions. It's likely to have the same compatibility issues as a). Most /do/ use the same name for resource and content so it might require more authors to change their chrome.manifest to opt-out of visibility -- somewhere between a) and b).

I think Benjamin owns the chrome.manifest mechanism: any thoughts?
Flags: needinfo?(dveditz) → needinfo?(benjamin)
Keywords: privacy, sec-want
Summary: SCRIPT tags can access resource → custom resource://foo/ allows fingerprinting addons
Do we know why greasemonkey is using resource: ? I don't know whether web content needs access to resource: at all nowadays, but I know I'd prefer greasemonkey to just stop doing this rather than introducing extra complexity to this handler.

We could also just try making resource: not web-accessible and see what breaks.
Flags: needinfo?(benjamin)
Our built-in image/plugin document styling uses resource://

I assume we'd whitelist resource://gre/ or something?
The only reason extensions would need to use resource: is to make things available to web content. I think this should be WONTFIX unless there's some other property of resource: that an extension really needs.
(In reply to Benjamin Smedberg  [:bsmedberg] from comment #5)
> The only reason extensions would need to use resource: is to make things
> available to web content.

To use JSM in Firefox 3.x you had to load from a resource:// URI. This hasn't been the case in a long while, but people learned this to be the case. (see bug 675372 comment 9 and later) Some addon authors haven't necessarily had a good reason to switch to chrome:// URIs. You'll need to for restartless addons, but I suspect many old addons still use resource://.
I'm trying to enumerate mechanisms to protect against this today, before it's fixed in FF proper. I don't have too much right now.  Some thoughts I haven't tested include:

1) Trying to unregister any default fingerprintable URL with setSubstitution, and registering a whole new one using a random ID
2) Migrating everything over to chrome:// with contentaccessible=no (but this probably won't work in some  use cases.)

Are there other ideas or techniques people could try and use today?
(In reply to Tom Ritter from comment #7)
> 2) Migrating everything over to chrome:// with contentaccessible=no

All chrome:// URIs are contentaccessible=no; you don't need to specify that.
Whiteboard: [fingerprinting]
Steps to reproduce:
http://scriptish.org/2011/09/02/how-to-detect-greasemonkey.html
(url is unavailable)

The appropriate code is:

<script type="text/javascript" src="resource://greasemonkey/addons4.js"></script>
<script type="text/javascript">
if (typeof GM_addonsStartup !== "undefined") {
  alert("I smell a monkey!");
}
</script>
Blocks: 1120398
See Also: → 1272383
Component: Security → Networking
Keywords: sec-wantsec-low
is this a dup of bug 863246 ?
Component: Networking → Security
(In reply to Benjamin Smedberg  [:bsmedberg] from comment #5)
> The only reason extensions would need to use resource: is to make things
> available to web content. I think this should be WONTFIX unless there's some
> other property of resource: that an extension really needs.

They are extensively used as a less privileged alternative to chrome:// URIs especially in SDK-based add-ons. I think we should only expose them to add-ons (including unprivileged resource:// pages or WebExtensions). With web_accessible_resources (https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json/web_accessible_resources) in WebExtensions, we should stop exposing arbitrary resources to content. Since the moz-extension: protocol is randomized, it is less harmful to privacy.

In short: Add-ons need resource: URIs. Not Web sites. For add-ons that need to expose resources to content, there is web_accessible_resources from WebExtensions.

Core packages like resource:/// or resource://gre/ should only be available to add-ons, just like the Components global.
Why expose JSMs and default preferences to content? (Not an obvious security issue, but bad for privacy)
Depends on: 863246
(In reply to bugzilla-ng from comment #13)
> Why expose JSMs and default preferences to content? (Not an obvious security
> issue, but bad for privacy)

See comment 4. Could be fixed by segregating the required resources into their own namespace (resource://gre-public/ ?) and hiding all the others.
This whole problem is going away with WebExtensions anyway.
(In reply to Limited Availabilty till Oct | Tom Schuster [:evilpie] from comment #15)
> This whole problem is going away with WebExtensions anyway.

Yes, WebExtensions are not able to use resource:// URI.
Meanwhile, bug 863246 is landing and it would fix the issues described in this bug.
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.