Extend CSP script-src hashes
WebKittens
@annevk
Title of the proposal
Extend CSP script-src hashes
URL to the spec
https://www.w3.org/TR/CSP3/
URL to the spec's repository
https://github.com/w3c/webappsec-csp/compare/main...carlosjoan91:webappsec-csp:main
Issue Tracker URL
No response
Explainer URL
https://github.com/explainers-by-googlers/script-src-v2/blob/main/README.md
TAG Design Review URL
Not filed yet
Mozilla standards-positions issue URL
https://github.com/mozilla/standards-positions/issues/1277
WebKit Bugzilla URL
No response
Radar URL
No response
Description
This feature adds two new prefixes to hashes in script-src directives (url- and eval-) and a new keyword (strict-dynamic-url).
Note that we originally intended to add these to a new directive called script-src-v2. At the moment, we are adding them to the existing script-src directive only, but the explainer and other text may still refer to script-src-v2.
url- hash prefix
This enables allowlisting scripts by their URL's hash:
Content-Security-Policy: script-src 'url-sha256-SHA256("https://example.com/script.js")';
<script src="https://example.com/script.js"></script>
eval- hash prefix
eval- prefix enables allowlisting eval'ed scripts by their hash, obviating the need to use unsafe-eval:
Content-Security-Policy: script-src 'eval-sha256-SHA256("console.log('Hello World')';
<script>
eval("console.log('Hello World')");
</script>
strict-dynamic-url
One of the main goals of this change is to keep compatibility with old browsers. To do this, it introduces a new keyword called strict-dynamic-url. This keyword allows using url hashes in a single, combined policy in both old and new user agents like so:
Content-Security-Policy: script-src https: 'unsafe-inline' 'strict-dynamic-url' url-hash-EXRatbw5eQNZwUCOApq3KI4p5S8ou8jvXBOolnXEg0k='
Old user agents will treat this policy as https: 'unsafe-inline', whereas new user agents will treat it as 'strict-dynamic-url' url-hash-EXRatbw5eQNZwUCOApq3KI4p5S8ou8jvXBOolnXEg0k='. Using strict-dynamic wouldn't work here, as it would cause old user agents to ignore the 'https:' source.