Websites can observe CSP violations from content scripts
Categories
(WebExtensions :: General, defect, P2)
Tracking
(Not tracked)
People
(Reporter: mixedpuppy, Unassigned)
References
(Depends on 1 open bug, Blocks 1 open bug)
Details
(Whiteboard: [addons-jira])
Attachments
(2 files)
If an addon content script triggers a violation against a pages csp the page can be notified via cspviolationevent. This can happen via content.fetch in the content script.
Comment 1•5 years ago
|
||
This bug followed from the thread at https://phabricator.services.mozilla.com/D48107?id=176093#inline-298599
In that thread, I didn't ask for a change in functionality, but to add explicit checks to make sure that cspviolationevent is fired iff the event is expected for the individual test cases in that file. So if a request was blocked by the content script's CSP, then the event should not fire (otherwise, if blocked by the page, the event should fire).
I assumed that that was already the behavior of that current patch, but if not, then we should indeed look into it.
content.fetch
is documented to behave as if it were to be called by the page (well, without extension permissions), so triggering a cspviolationevent
when it's blocked doesn't look too wrong to me.
Reporter | ||
Comment 2•5 years ago
|
||
Then this will likely be closed at some point.
Given the amount of tests for the violation event, I doubt that there is an issue with pages getting those, the concern is more that pages don't get moz-extension violations. however I just modified the test.
Comment 3•4 years ago
|
||
Resetting priority for triage. This should be a higher priority as this is not only visible in cspviolationevent
events, but also in CSP reports (report-to
/ report-uri
). CSP reports can be triggered even when JavaScript is disabled on a website.
These CSP reports include the URL of the script that triggered the failure, in the case of extensions that's the moz-extension://UUID
format, which can be abused for fingerprinting (like bug 1405971).
CSP violations triggered by content scripts should ideally not be reported to the website, or at least the extension UUID should be sanitized.
CSP violation events should ideally still be triggered in the content script for extensions, to allow them to work. This may be difficult since the target of the CSP violation event is a DOM element, the content script and the web page share the same document
object (inside the content script sandbox, the document
is seen with Xray vision though).
Reporter | ||
Updated•4 years ago
|
Reporter | ||
Comment 4•4 years ago
|
||
Christoph, can you help outline what should happen to filter extension csp violations?
Comment 5•4 years ago
|
||
I would have thought we only report the scheme
, in that case moz-extension
as the blocked-uri
or also document-uri
because we call StripURIForReporting for both of those. Is that not what's happening?
Or is it the sourcefile
, line-number
, and column-number
that leaks info? I guess we could surpress that info in case of a moz-extension
scheme. Or is there yet something else?
Updated•4 years ago
|
Reporter | ||
Comment 6•4 years ago
|
||
I looked into (and tested) this.
a) we don't expose moz-ext in any reports that go to the report-uri, at least not in any of the test coverage that we have (e.g. test_ext_contentscript_csp.js).
b) the proposal to have content scripts receive violation reports, but not the page, seems pretty difficult when using content.fetch
(etc).
While a content script can trigger a violation report in the page and to the report-uri, I do not see any leaked data (other than the ping itself).
These CSP reports include the URL of the script that triggered the failure, in the case of extensions that's the moz-extension://UUID format
Rob, do you have an STR that produces that? Or was this just an assumption?
Comment 7•4 years ago
|
||
STR is a content script that injected an inline script tag.
STR:
- Install version 4.23.1 of https://addons.mozilla.org/en-US/firefox/addon/dont-track-me-google1/versions/
- Visit google.com
- Open the console, and look for errors and/or network requests.
Expected:
- No CSP errors
Actual:
- Error in console:
Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”).
- Network request to the
cspreport
endpoint atconsent.google.com
with the following request body (formatted for readability):
{
"csp-report": {
"blocked-uri": "inline",
"column-number": 48,
"document-uri": "https://consent.google.com/intro/?continue=https://www.google.com/?gws_rd%3Dssl&origin=https://www.google.com&if=1&gl=NL&hl=nl&pc=s",
"line-number": 372,
"original-policy": "script-src 'nonce-/Ga0rEw7ulvlYYM7QbOYOw' 'unsafe-inline'; object-src 'none'; base-uri 'self'; report-uri https://consent.google.com/_/ConsentUi/cspreport; worker-src 'self'",
"referrer": "https://www.google.com/",
"source-file": "moz-extension://671262ee-f895-4ee8-b175-a3fc2b9aae38/contentscript.js",
"violated-directive": "script-src"
}
}
Reporter | ||
Comment 8•4 years ago
|
||
This test isn't how we want it in a final patch, but it does throw right now.
Comment 9•4 years ago
|
||
We have also encountered this issue in the DuckDuckGo extension and will be shipping a fix to block reports with moz-extension://
URLs in our next release.
We consider this a critical issue, as it exposes a strong user identifier to sites which persists history/storage clearances. Additionally, if an affected extension is enabled in private windows, this identifier is persisted there. A test page which demonstrates the issue is available here: https://privacy-test-pages.glitch.me/security/csp-report/index.html. Using this we found several other popular extensions leaking extension IDs this way:
- Adguard
- AdBlocker Ultimate
- Privacy Badger
- LastPass
- Dark Reader
- SingleFile
Note, some extensions, like uBlock Origin, block all csp-reports and therefore protect against this.
Comment 10•4 years ago
|
||
With the patch from bug 1705523, the UUID won't be leaked any more. CSP reports will then look like "source-file": "moz-extension"
.
I'll leave this bug open for the purpose of preventing CSP reports for extension scripts.
The CSP spec generally states that extensions should be exempt from the CSP.
But failing that, the least that we can do is to not generate CSP violation reports for it (like Chrome does).
Comment 11•4 years ago
|
||
The CSP spec generally states that extensions should be exempt from the CSP.
Is that bug 1267027?
Comment 12•4 years ago
|
||
(In reply to Alexei from comment #11)
The CSP spec generally states that extensions should be exempt from the CSP.
Is that bug 1267027?
Yes. Specifically the text quoted at https://bugzilla.mozilla.org/show_bug.cgi?id=1267027#c20
Comment 13•4 years ago
|
||
For people who are following this bug: until this bug is resolved, CSP violations from extensions can still trigger reports.
Although the patch from bug 1705523 will prevent the UUID from leaking, it doesn't prevent CSP reports from happening. So if your extension injects a (dynamically generated or static) inline script, and the website has enabled the "report-sample" directive, then the start of the inline script will be reported to the CSP endpoint. That's problematic if the inline script contains sensitive data.
Note that extensions shouldn't be injecting sensitive data via inline scripts anyway, even without CSP violation reports they could detect inline scripts via mutation observers.
Comment 14•2 years ago
|
||
Dropping S3 to S2 because the UUID leak has been resolved (comment 10). As comment 13 noted, there is still the report-sample
leak (but even if that is fixed, mutation events can still be used to extract the info, unless the <script>
is part of a closed shadow DOM tree).
There has been work to identify the CSP to use for extension-inserted content (bug 1267027). It should be feasible to at least stop propagation of these violations to web pages. Secondarily, it would be nice if extensions can detect violations within their content script, but that is not a must-have blocker for this bug.
Side note: if we can reliably associate inline <script>
with extension CSP, then it would be nice to make it independent of web pages (or at least for window.eval
- bug 1591983), since that appears to be the canonical way to run scripts in the page's content from a content script (also relied upon in the initial version of the userScripts API - https://github.com/w3c/webextensions/issues/279 / https://github.com/w3c/webextensions/pull/331). I also see extensions removing the CSP with the webRequest API to get around this issue (but bug 1736575 would also be a good alternative for that use case).
Updated•2 years ago
|
Comment 15•2 years ago
|
||
Comment 16•2 years ago
|
||
I saw this bug and decided to implement a somewhat limited solution for this. It suppresses sending CSP reports and the "securitypolicyviolation" event when the source-file is a moz-extension: URL and the document is http(s). That was the best solution that I could come up with that shouldn't block it in too many cases. e.g. for data: URLs we don't necessarily know if it's running an extension or web context.
We will still show the console error in any case.
Description
•