-
Notifications
You must be signed in to change notification settings - Fork 78
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
Choose a consistent model for workers under nonce-based policies #375
Comments
@mikewest and @andypaicu, I'd appreciate your thoughts on why this is a terrible thing to do :) |
I unfortunately am also not excited about the options. Overall I would probably go for 3. or 4. What would I don't know about deciding the worker CSP inheritance issue based on trying to make it somewhat help address this issue. I would rather w3ctag/design-reviews#310 end up helping decide one and for all. |
The main drawback of (3) is that the platform would not allow developers to use these APIs unless they relax their policies and allow the execution of all non-parser-inserted scripts created at runtime with This seems somewhat undesirable for developers because injections into APIs like I guess another option mentioned by @mikewest would be to make |
It's a bit unfortunate that OP doesn't split out the last set of paragraphs as 5, as that's what I'd vote for. |
I don't think the last paragraph actually solves the problem though. Workers having their only policy does not solve the problem of nonce-based policies not allowing |
Then, based on this, I'd go with (4) or maybe with (0) do nothing and accept this as a limitation of purely nonce based policies. |
I think doing nothing on the CSP side is a reasonable option, especially if we can: a) relax the fail-closed model of What I'd really like to avoid is pushing developers who deploy safe policies which require a nonce for every script load to relax them by requiring |
@dveditz pointed out that these same APIs are a problem for features which require scripts to have a valid |
Right -- that would be one argument in favor of some variant of 1) such as passing in a dictionary of optional params so we could have an integrity argument as well as an extensibility point next time something like this comes up. On the other hand I'm not sure nonces make a lot of sense for imports from a worker. nonces only work if they're dynamic, which means it has to be passed into the worker somehow and the importScript calls are now dynamic and another place something might get injected. They're obviously no protection at all if the worker itself is malicious, but you've already lost at that point. My preference keeps flipping between options 2 and 3 at which point I throw up my hands and pick 4, horrifying myself. I don't like that importScripts() and import() are different though. We do need to fix that. |
I'd like to clarify: if we did #2 (fail open) I'd want that to apply only if a nonce (or 'strict-dynamic') was specified in the policy. If the policy used a domain whitelist we should obviously enforce it. Pretty sure that's what you meant, but if you meant "fail open always" I'd love to hear the arguments in favor. |
This is a complicated issue about which we've had several discussions discussions over the years (e.g. #15, #146, and partly #243).
The crux of the problem is that JS APIs which allow the loading of external scripts (e.g.
importScripts()
in workers or dynamic module imports) do not provide any way for developers to invoke them with a script nonce. Users of policies which rely on script nonces to convey trust thus either can't use these APIs, or can't use safe "nonce-only" policies. Worse, there is no consistency between APIs when it comes to whether they fail open or fail closed:importScripts()
fails closed. Under a nonce-only policy (script-src 'nonce-foo'
), authors don't have a way to invoke this API. Note that if the policy uses'strict-dynamic'
,importScripts
is implicitly allowed to execute as per 'strict-dynamic' should bless programmatically added workers #200 so developers need to use policies with'strict-dynamic'
rather than more restrictive policies based purely on nonces, even if they've done the work to manually propagate nonces to other scripts loaded at runtime.import("/foo.js")
) fail open. Under a nonce-only policy there is no way to restrict the loading of additional modules via this API, as discussed in Any protection against dynamic module import? #243In practice, this forces users to add
'strict-dynamic'
to their policies, making it less likely that applications in the future will be able rely on safer policies with manual nonce propagation.There are several ways in which we could handle this:
importScripts()
to accept anonce
parameter and require it to be present for nonce-based policies which don't setstrict-dynamic
.'strict-dynamic'
scoped to just these APIs:TrustedResourceUrl
toimportScripts()
.)'strict-dynamic'
with nonce-based policies if the application uses either of these APIs.'strict-dynamic'
-like behavior only for these APIs.None of the options above seems particularly appealing to me. However, what might be a reasonable workaround at least in the context of workers (where the problem with
importScripts()
manifests) is to treat Web Workers similarly to Shared- and Service Workers and use a policy specified by the response carrying the worker (this was suggested in #146 (comment) and is the current behavior in Firefox). This would at least allow developers to specify a different policy for their workers, i.e. the main application could use a nonce-only policy, and the one sent with the worker could contain'strict-dynamic'
. This definitely doesn't address the underlying problem of inconsistent behavior for these APIs, but would give developers a path to having safer nonce-based policies for their applications. If we do this then we could either ignore the inconsistency outlined above, or pick a simple solution, e.g. (2).It's also a somewhat compelling reason to treat Web Workers more similarly to Shared- and Service Workers; the current difference in behavior seems fairly confusing to most developers.
The text was updated successfully, but these errors were encountered: