CSP: script-src-elem 'self' blocks scripts served by service worker when requested from a dynamically created srcless iframe using document.write()
Categories
(Core :: DOM: Service Workers, defect, P3)
Tracking
()
People
(Reporter: mehdi.rande, Unassigned)
References
Details
Attachments
(1 file)
|
1.19 KB,
text/html
|
Details |
Steps to reproduce:
- Serve all files with the CSP header:
default-src 'self' ws: wss: blob: 'unsafe-inline' 'unsafe-eval' index.htmlcontains:- A service worker registration pointing to
sw.js - A script that dynamically creates a srcless iframe
- A script injected inside that iframe:
<script src="/iframe-script.js" crossorigin="">
- A service worker registration pointing to
sw.jsintercepts requests to/iframe-script.jsand serves them viafetch(event.request)or via cache.iframe-script.jscontains a simpleconsole.log- Load the page a first time to register the service worker
- Reload the page so the service worker is active and intercepts the request to
iframe-script.js
Index.html sample is attached.
sw.js only contains :
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname === '/iframe-script.js') {
event.respondWith(fetch(event.request));
}
});
iframe-script.js content does not matters
Actual results:
CSP blocks the script execution with the error:
Content-Security-Policy: The page's settings blocked a script (script-src-elem) at http://localhost:8080/iframe-script.js from being executed because it violates the following directive: "script-src-elem 'self' 'unsafe-inline' 'unsafe-eval'"
The error origin is reported as blank, suggesting Firefox evaluates the CSP in the context of the srcless iframe (opaque origin) rather than the parent page when the response is served by a service worker.
Expected results:
The script should execute successfully. 'self' should match the same-origin URL http://localhost:8080/iframe-script.js in the context of the parent page's CSP, as it does in Firefox 147, Chrome, and in Firefox 148 without a service worker active or when the iframe is not dynamically created.
Comment 1•2 months ago
|
||
The Bugbug bot thinks this bug should belong to the 'Core::DOM: Service Workers' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.
Comment 2•2 months ago
|
||
An interesting nuance here which may be irrelevant but is notable is that document.write is being used with the iframe in index.html:
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
console.log('[Page] iframe created dynamically');
const doc = iframe.contentDocument || iframe.contentWindow.document;
doc.open();
doc.write('<html><head></head><body></body></html>');
doc.close();
const script = doc.createElement('script');
script.src = '/iframe-script.js';
script.crossOrigin = '';
doc.head.appendChild(script);
console.log('[Page] Script injected in iframe');
For iframes the case generally should be that the CSP should be inherited into the iframe from the parent on the Client, but if we are re-creating the Client, something could be going wrong there.
Comment 3•1 month ago
|
||
We have known issues with 'self', but if this is actually specific to ServiceWorkers it might be something a bit different.
| Reporter | ||
Comment 4•1 month ago
|
||
Thank you for the quick response and for linking to #1899512.
Could you clarify the FIXED resolution? Since #1899512 is still open, we're not sure whether our specific case is already covered by an in-progress fix, or if this should rather be marked as DUPLICATE.
Knowing the target Firefox version for the fix would also help us plan the removal of the workaround we've had to put in place. This pattern — dynamically created srcless iframes with injected scripts — is how GWT loads its compiled assets, which we have limited control over, making a clean fix on our side difficult.
Thanks again!
Updated•1 month ago
|
Comment 6•1 month ago
|
||
According to Google AI (which may be biased in this case) the GWT is still in wide use, so I feel that P3/S3 is not urgent enough. I really hate to point my users to Chrome/Edge after I trained them to use Firefox for years...
Description
•