Closed
Bug 1399284
Opened 7 years ago
Closed 7 years ago
CSP bypass with importScripts
Categories
(Core :: DOM: Security, defect)
Core
DOM: Security
Tracking
()
RESOLVED
WORKSFORME
People
(Reporter: s.h.h.n.j.k, Unassigned)
Details
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36 Steps to reproduce: 1. Go to https://test.shhnjk.com/csp_external.html Actual results: Received message from cross-origin js file. Expected results: CSP "script-src 'self'" is defined on the page. Thus importScripts to cross-origin js file should be blocked.
Comment 1•7 years ago
|
||
Christoph, this one seems up your alley as well. Let me know if there's other people I should be pinging when I see this type of bug come in. :-)
Group: firefox-core-security → core-security
Component: Untriaged → DOM: Security
Flags: needinfo?(ckerschb)
Product: Firefox → Core
Version: 1.0 Branch → Trunk
Comment 2•7 years ago
|
||
(In reply to Jun from comment #0) > CSP "script-src 'self'" is defined on the page. Thus importScripts to > cross-origin js file should be blocked. This is a sad, sad story in 3 acts. 1. Originally as we proposed it script-src covered workers, and that's how we implemented it. 2. The standards committee--of which we're part, to be sure--decided, however, that since in some ways Shared Workers and especially Service Workers have a lifetime independent of the original document they were more like iframes, and thus the "child-src" directive was born. This is how the official "CSP2" standard defines things. We implemented this and ended up breaking a lot of our own internal stuff that assumed workers were covered by script-src (mostly in Firefox OS, where we used CSP to help sandbox apps). 3. In CSP 3 (not anywhere close to official) we decided the CSP2 change was lame and that workers really were scripts after all. 'worker-src' was added to the spec and the fall-back was defined as script-src rather than child-src (which now became deprecated). Firefox has not implemented the CSP3 change yet: workers are still controlled by child-src (with default-src fallback). Although this change is certainly more logical (the reason we proposed it 7 years ago) actually adopting it can break sites, or leave them vulnerable if they think workers are covered but they aren't. The change will probably go through anyway since Chrome has adopted it and Google is one of the few of sites that actually use CSP, and we won't want Firefox users to be unsafe on Google's high-traffic sites.
Status: UNCONFIRMED → RESOLVED
Closed: 7 years ago
Resolution: --- → DUPLICATE
Comment 3•7 years ago
|
||
Actually, the policy is _only_ script-src here. No child-src so workers should fallback to default-src. But there's no default-src. Shouldn't the behavior assume default-src 'none' in that case, since at least one -src directive was specified? Need to check the spec on that.
Status: RESOLVED → REOPENED
Ever confirmed: true
Resolution: DUPLICATE → ---
Comment 4•7 years ago
|
||
Looks like we're doing the right thing: "Let the default sources be the result of parsing the default-src directive’s value as a source list if a default-src directive is explicitly specified, and otherwise the U+002A ASTERISK character (*)."
Status: REOPENED → RESOLVED
Closed: 7 years ago → 7 years ago
Resolution: --- → DUPLICATE
Updated•7 years ago
|
Group: core-security → core-security-release
Reporter | ||
Comment 5•7 years ago
|
||
I've changed "script-src 'self'" to "default-src 'self'" and it still works. https://test.shhnjk.com/csp_external.html
Flags: needinfo?(dveditz)
Comment 6•7 years ago
|
||
both import.js and worker.js are same-origin, and match 'self'. Maybe you want to move the import.js stuff inline, then use a CSP of: default-src 'none'; script-src 'unsafe-inline';
Flags: needinfo?(dveditz)
Reporter | ||
Comment 7•7 years ago
|
||
https://test.shhnjk.com/import.js var myWorker = new Worker("worker.js"); myWorker.onmessage = function(e) { document.body.innerHTML=e.data; } https://test.shhnjk.com/worker.js importScripts("https://attack.shhnjk.com/worker.js"); https://attack.shhnjk.com/worker.js postMessage("Message from attacker!"); postMessage comes from https://attack.shhnjk.com/worker.js which is cross-origin.
Comment 8•7 years ago
|
||
oops, stopped too soon. --TWO-- workers are involved and it's the second one we're looking at.
Status: RESOLVED → REOPENED
Resolution: DUPLICATE → ---
Comment 9•7 years ago
|
||
(In reply to Jun from comment #5) > I've changed "script-src 'self'" to "default-src 'self'" and it still works. > > https://test.shhnjk.com/csp_external.html When loading the example from https://test.shhnjk.com/csp_external.html I observe the following: 1) The test page loads > <meta http-equiv="Content-Security-Policy" content="default-src 'self';"> > <script src="import.js"></script> which means that self translates into https://test.shhnjk.com 2) CSP checks if import.js is loaded from https://test.shhnjk.com, it is: > https://test.shhnjk.com/import.js CSP CHECK: OK 3) import.js loads > var myWorker = new Worker("worker.js"); > myWorker.onmessage = function(e) { > document.body.innerHTML=e.data; > } which loads the worker from https://test.shhnjk.com/worker.js CSP CHECK: OK 4) the worker then loads: importScripts("https://attack.shhnjk.com/worker.js"); Within (4) we miss the CSP check, I guess because we are not propagating the CSP to the worker?!?
Flags: needinfo?(ckerschb)
Comment 10•7 years ago
|
||
Your worker doesn't have a CSP. Only workers from a "unique origin" (data:, mostly) inherit a CSP; for all others they need their own sent as an http header: https://www.w3.org/TR/CSP2/#processing-model-workers [this is related to the sad story I told in comment 2. Originally workers inherited always, but with shared workers that became a problem.]
Reporter | ||
Comment 11•7 years ago
|
||
Okay, sorry for that. I need to study spec more :(
Updated•7 years ago
|
Status: REOPENED → RESOLVED
Closed: 7 years ago → 7 years ago
Resolution: --- → WORKSFORME
Updated•4 years ago
|
Group: core-security-release
You need to log in
before you can comment on or make changes to this bug.
Description
•