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

Behavior of worker-src 'strict-dynamic' #609

Open
evilpie opened this issue Jul 5, 2023 · 8 comments
Open

Behavior of worker-src 'strict-dynamic' #609

evilpie opened this issue Jul 5, 2023 · 8 comments

Comments

@evilpie
Copy link
Contributor

evilpie commented Jul 5, 2023

I have a question about the behavior of explicitly worker-src 'strict-dynamic'. Workers are obviously not parser-inserted so for script-src and script-src-elem the Script directives pre-request check should allow them in step 1.4. However unlike the script-src(-elem) Pre request check, the worker-src Pre-request Check doesn't call into the "Script directives pre-request check".

Firefox currently only supports 'strict-dynamic' in script-src(-elem|attr) so this isn't allowed. Chrome seems to allow the execution of every Worker with that policy. Considering that Workers also fallback to child-src a similar question applies, but I haven't tested it.

Edit: We are currently working on implementing support for 'strict-dynamic' in the default-src in Firefox: bug 1313937

@antosart
Copy link
Member

For chrome, I could dig up bug 708982.

The spec seems to mandate something else. As pointed out above, I think allowing this makes most sense, so I would propose to fix the spec. We should also write a WPT.

@bakkot
Copy link

bakkot commented Dec 18, 2023

#200 (comment) claims that it does, but even as of the commit mentioned in that issue I don't see how. cc @mikewest

And I'm not sure exactly what it's supposed to do. Is there any way of loading a worker which would be blocked by worker-src 'strict-dynamic'? If not, it's kind of silly that worker-src 'strict-dynamic' is less strict than worker-src *.

@antosart
Copy link
Member

antosart commented Dec 19, 2023

There is actually a test for this, and it seems to pass on all vendors.

Edit: The test is actually for script-src 'strict-dynamic', and according to the spec script-src 'strict-dynamic' should allow all workers. I don't know what vendors implement for worker-src 'strict-dynamic', but according to the spec that should not allow workers. It's not clear to me why one would need worker-src 'strict-dynamic' though.

@bakkot
Copy link

bakkot commented Dec 19, 2023

There is actually a test for this

The test case I'm using is

<meta http-equiv="content-security-policy" content="script-src 'nonce-abc'; worker-src 'strict-dynamic'">
<script nonce=abc>const myWorker = new Worker("./worker.js");</script>

and at least on my machine, in Safari, that does not load the worker.

Screenshot 2023-12-19 at 7 21 34 AM

I don't know what vendors implement for worker-src 'strict-dynamic', but according to the test that should not allow workers.

Where are you seeing that in the test? FWIW at least Chrome and Friefox appear to allow workers with the snippet I have above.

It's not clear to me why one would need worker-src 'strict-dynamic' though.

In my case, I want the ability to load workers, but I can't put script-src 'strict-dynamic' because the presence of 'strict-dynamic' disables host-source directives and the script-src of the page in question uses host-source directives.

@antosart
Copy link
Member

Where are you seeing that in the test? FWIW at least Chrome and Friefox appear to allow workers with the snippet I have above.

Sorry, I meant "according to the spec", not "according to the test". I opened a PR just to test worker-src 'strict-dynamic' here and it seems that Chrome and Firefox allow workers while Safari blocks.

In my case, I want the ability to load workers, but I can't put script-src 'strict-dynamic' because the presence of 'strict-dynamic' disables host-source directives and the script-src of the page in question uses host-source directives.

Can't you use worker-src * blob:; script-src ...?

@bakkot
Copy link

bakkot commented Dec 19, 2023

Sorry, I meant "according to the spec", not "according to the test". I opened a PR just to test worker-src 'strict-dynamic'

Ah, ok. FWIW the spec currently treats loading of workers identically regardless of whether the effective directive is script-src or worker-src, so there shouldn't be a difference. Thanks for submitting the test!

Can't you use worker-src * blob:; script-src ...?

Yes in theory, but for whatever reason the engineers at the property in question are not OK with blob: but are OK with 'strict-dynamic'. (Presumably because there is lots of stuff out there saying "blob is equivalent to unsafe-eval" but nothing which says "strict-dynamic is equivalent to unsafe-eval", and engineers have to rely on guidance like this.)

I was going to point out that strict-dynamic was strictly more permissive, but then I ran into this bug, which meant I couldn't actually justify that claim.

@evilpie
Copy link
Contributor Author

evilpie commented Dec 20, 2023

Ah, ok. FWIW the spec currently treats loading of workers identically regardless of whether the effective directive is script-src or worker-src, so there shouldn't be a difference. Thanks for submitting the test!

Can you clarify that? When we use a script-src directive for worker requests, we end up in 6.7.1.1. Script directives pre-request check, which handles 'strict-dynamic'. worker-src just uses 6.7.2.4. Does request match source list?.

@bakkot
Copy link

bakkot commented Dec 20, 2023

Ah jeeze, you're right. I thought that the way it worked was the worker-src pre-request steps ran using the contents of the script-src directive, but no, it's actually the script-src directive steps which run. default-src and child-src handle fallbacks the way I was thinking, but script-src works differently.

So you're right, script-src and worker-src are treated differently. But the spec does treat loading of workers identically regardless of whether the effective directive is default-src or worker-src.

So you have the very strange situation that strict-dynamic is respected for workers only if it is present in a script-src directive specifically - not if there's a worker-src which prevents falling back, nor if the fallback ends up being default-src instead.

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