LiCybora / NanoDefenderFirefox

An anti-adblock defuser for uBlock Origin on Firefox
GNU General Public License v3.0
368 stars 16 forks source link

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

Open ntninja opened 3 years ago

ntninja commented 3 years ago

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.

xelaseer commented 3 years ago

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

Genuine question.

ntninja commented 3 years ago

@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 commented 3 years ago

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 commented 3 years ago

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