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

Extension acts as fingerprinting beacon on strict CSP with report-uri sites #196

Open
ntninja opened this issue Dec 9, 2020 · 4 comments

Comments

@ntninja
Copy link

ntninja commented Dec 9, 2020

Many websites nowadays use a security technology called Content Security Policy (CSP) to limit what attackers can do in case of compromise on the site. When deployed with strict settings this prevents any use of eval or <script> tags to execute JavaScript code on-the-fly: All of the page's scripts (and also CSS, etc) must be served from a set of trusted origins specified in the policy instead. This rule also applies to any scripts injected by extensions using window.eval or document.createElement("script").

The above would only render NanoDefender Pro ineffective on such sites, however CSP includes another feature that many sites use to monitor the issues caused by their CSP in the field called report-uri: Using this, a site can specify an arbitrary URL to be pinged whenever the browser detects a CSP violation. This again includes violations caused by extension scripts, like on the following example page (https://mm-csp-example.herokuapp.com/ was set up to test a related CSP issue with another extension):

{
  "csp-report": {
    "blocked-uri": "inline",
    "column-number": 33,
    "document-uri": "https://mm-csp-example.herokuapp.com/",
    "line-number": 214,
    "original-policy": "default-src 'self'; connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'; report-uri https://mm-csp-example.herokuapp.com/report_csp",
    "referrer": "",
    "source-file": "moz-extension://22f938b7-43d7-410d-91c6-80262d30dbd7/content/core.js",
    "violated-directive": "script-src"
  }
}

This can even include “samples” of the blocked content like in the following real-world example of undisclosed origin:

{
  "csp-report": {
    "blocked-uri": "inline",
    "column-number": 33,
    "document-uri": "",
    "line-number": 214,
    "original-policy": "default-src 'none'; connect-src 'self' …; font-src 'self' … data:; img-src 'self' … data: …; script-src 'report-sample' 'self' 'unsafe-eval' …; object-src …; manifest-src …; media-src …; style-src 'self' 'unsafe-inline'; frame-src …; worker-src …; report-uri …/csp",
    "referrer": "",
    "script-sample": "(() => {\n        try {\n            let _…",
    "source-file": "moz-extension://22f938b7-43d7-410d-91c6-80262d30dbd7/content/core.js",
    "violated-directive": "script-src"
  }
}

If that isn't a textbook example of a perfect fingerprinting vector based on the list of installed non-CSP-compliant extensions then I don't know. Even without the “script sample”, the combination of “just” the script name and line and column numbers is likely enough to unique identify every CSP violating extension in existence. And as I've discovered today, yours is by far not the only extension causing these kinds of reports to be generated.

So how to fix this? Well, the inject function and everything calling it will have to be rewritten in terms of the recommendations of the MDN article on Sharing objects with page scripts. In particular this means: Accessing page objects only through the .wrappedJSObject accessor (“X-Ray Vision”) and exporting objects from the content-script to the page scope using exportFunction/cloneInto only. Unfortunately, this whole concept is completely foreign to Chromium-based browsers (where using window.eval and related techniques is indeed the right thing to do), so the whole code currently in place needs to be retained if you want to continue supporting non-Firefox browsers as well.

gorhill added a commit to gorhill/uBlock that referenced this issue Dec 11, 2020
@xelaseer
Copy link

@ntninja is this not solved by uBlock Origin blocking CSP reports by default?

Genuine question.

@ntninja
Copy link
Author

ntninja commented Dec 15, 2020

@xelaseer: I tried a clean installation of uBlock Origin and it does not appear to enable that option by default?

I guess if it (retroactively) enabled that option by default that would mitigate that issue for NanoDefender specifically (which can rely on uBlock Origin being installed). The relationship between that option and on NanoDefender causing reports to be generated would of course still be opaque at best. That is: So people disabling the option will be unlikely to realize that it not only affects legitemate CSP reports generated by the site, but also reports of misbehaving extensions.

I would help with the issue at hand of course, yes. It's not a solution however.

@gorhill
Copy link

gorhill commented Dec 15, 2020

I consider that ultimately the fix needs to be in Firefox, it's essentially leaking was is meant to be private information (the unique id of an extension) into the outside world.

@gorhill
Copy link

gorhill commented Aug 6, 2021

Fixed in Firefox 90: https://bugzilla.mozilla.org/show_bug.cgi?id=1705523

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants