-
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
Enable CSP3 'unsafe-hashes'
for script src
attributes
#574
Comments
I don't think this is crazy, and could certainly enable some deployment improvements as we discussed at TPAC. I'm a little skeptical of the redirect bit in particular as well as the relative URLs, but I'm sure we could work something reasonable out if we talk through it (for example, we could require /cc @letitz @antosart; @annevk; and @ckerschb, @dveditz, and @mozfreddyb to weigh in from their browsers' respective perspectives. |
This sounds reasonable overall!
I don't follow this part. Can you elaborate? |
I'm not entirely enthused by this particular approach because I see this as more similar to how script nonce attributes work, i.e. if you add a nonce to That said, I do think it's good to think about this, e.g. consider whether this should perhaps be controlled by a separate keyword (
Assume browsers become more permissive in their interpretation of |
Makes sense, thanks! I don't terribly see the point of using a new keyword for the redirect support, but if we go that route, I cast my vote for |
tl;dr Let's allow CSP3
'unsafe-hashes'
to apply to<script src>
attributes to let developers allowlist scripts by their URL, as discussed at TPAC. This will make it possible to build tools to enable CSP on existing websites without requiring application changes.Background
The
script-src
andstyle-src
directives support hashes to allowlist resources that developers have explicitly enumerated and want to allow to be loaded in their applications. The'unsafe-hashes'
keyword lets developers use hashes to allowlist existing markup, such as inline event handlers, that would otherwise be incompatible with CSP and require a policy to include'unsafe-inline'
.All of this makes it possible to create flexible policies based on script hashes. Recent academic research has shown that such policies are generally safe for the majority of websites (see To hash or not to hash: A security assessment of CSP’s unsafe-hashes expression).
However, currently, websites that load external scripts (
<script src="...">
) need to choose between changing their markup to add dynamic per-responsenonce
attributes to be compatible with strict CSP, or using significantly less safe allowlist-based policies. (Allowing external JavaScript via hashes by hooking into Subresource Integrity unfortunately isn't practical in most cases because the hash applies to the content of the response, precluding the use of hashes for script responses that are dynamically generated or can otherwise change -- a large amount of popular script-based APIs fall into this category.)With this change, we'll allow developers to use fully hash-based policies (possibly with
'unsafe-eval'
and'strict-dynamic'
where necessary) without requiring application-level changes beyond setting the correct CSP header.Details
'unsafe-hashes'
already makes it possible to use hashes for a number of element attributes that allow script execution (e.g. inline event handlers, such asonclick
, orjavascript:
URIs). This change would allow a<script src=[URL]>
to execute if thescript-src
directive contains'unsafe-hashes'
and the hash of[URL]
is present in the list of hashes in the policy.This has the following consequences:
Unlike with host-source, we will not enforce the policy on each redirect when fetching a script; we'll only require the script's
src
attribute to have its hash added to the policy. This matches the behavior of setting anonce
attribute on a script -- as long as the original<script>
element has the correct nonce, it will be allowed to execute, even if the server redirects to a different URL.Developers will need to be careful about adding hashes for relative script URLs . To be safe, policies will need to also set a
base-uri
directive; this is already the case with strict CSP and covered in the Nonce retargeting note section of the spec.Note: Instead of applying to the value of the
src
attribute verbatim, we could consider first resolving the absolute URL and then applying the hash to it. E.g. https://site.example with<script src="/foo.js">
would need to computehash("https://site.example/foo.js")
instead of justhash("/foo.js")
. However, this would introduce problems for dev/test/staging environments because the hashes would be different; asking developers to usebase-uri
seems like a better choice here.Developers will be able to (and will have to) allowlist legitimately loaded URLs by including all of the parameters present in the request -- adding a hash for
https://site.example/foo.js?param=foo
will not allowhttps://site.example/foo.js?param=bar
to load. In cases where websites load scripts with dynamically generated scriptsrc
attributes, they will need to either use script nonces or'strict-dynamic'
in cases where these scripts are created at runtime (e.g. by JS libraries).We probably also want to do the same for
style-src
and<link rel=stylesheet href>
attributes.Why use hashes instead of verbatim URLs
See here. In short, the current way URLs work in CSP doesn't work in this case because host-source is checked on every redirect hop and for this reason it can't be granular enough (due to well-known concerns about leaking post-redirect URLs). Currently URLs also aren't compatible with
strict-dynamic
which, for backwards compability, ignores the host-source allowlist.An unintended benefit of using hashes is that they'd gracefully handle long URLs and URLs with metacharacters which would be problematic in an HTTP header.
It's arguably still fairly strange to use hashes this way. However, the practical benefit of allowing the adoption of strict CSPs without requiring developers to rewrite their markup seems worth it.
Backwards-compatibility
There are two issues to consider here:
'unsafe-hashes'
is not yet widely deployed. The change will make existing policies that use the keyword more permissive; however, it seems unlikely that hashes of e.g. inline event handlers can be used as values ofscript#src
attributes to give potentially injected markup any useful capabilities.'unsafe-hashes'
today, but don't apply it toscript#src
, policies that rely on the use of hashes forscript#src
will break. Developers will likely need to perform user-agent sniffing when setting such policies./cc @mikewest @lweichselbaum
The text was updated successfully, but these errors were encountered: