Bug 233071
| Summary: | Allowlisting empty elements via content hashes in CSP directives is inconsistent across browser engines | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Andy Bonventre <andybons> |
| Component: | WebKit Misc. | Assignee: | Matthew Finkel <m_finkel> |
| Status: | RESOLVED FIXED | ||
| Severity: | Normal | CC: | bfulgham, gsnedders, katherine_cheney, m_finkel, webkit-bug-importer |
| Priority: | P2 | Keywords: | InRadar |
| Version: | WebKit Local Build | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
| See Also: | https://github.com/web-platform-tests/wpt/pull/34902 | ||
Andy Bonventre
The following page will render a red background on Chromium and Gecko, but not WebKit due to a CSP violation:
<!DOCTYPE html>
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; style-src 'self' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='; script-src 'unsafe-inline'"
/>
<html lang="en">
<script type="module">
const style = document.createElement("style");
style.appendChild(document.createTextNode(""));
document.head.appendChild(style);
const { sheet } = style;
if (sheet) {
sheet.insertRule("body { background: red; }");
console.info("background should be red now");
} else {
console.error("no sheet found :(");
}
</script>
</html>
The <style> node is empty, so the sha256 of the empty string (sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=) allows for it to successfully apply to the page on Chromium and Gecko.
On WebKit, ContentSecurityPolicy::findHashOfContentInPolicies will always return false for an empty style element (see https://sourcegraph.com/github.com/WebKit/WebKit/-/blob/Source/WebCore/page/csp/ContentSecurityPolicy.cpp?L362)
A workaround on WebKit is to append some arbitrary content to the <style> tag:
<!DOCTYPE html>
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; style-src 'self' 'sha256-0hAheEzaMe6uXIKV4EehS9pu1am1lj/KnnzrOYqckXk='; script-src 'unsafe-inline'"
/>
<html lang="en">
<script type="module">
const style = document.createElement("style");
style.appendChild(document.createTextNode("/**/"));
document.head.appendChild(style);
const { sheet } = style;
if (sheet) {
sheet.insertRule("body { background: red; }");
console.info("background should be red now");
} else {
console.error("no sheet found :(");
}
</script>
</html>
From Kate Cheney in WebKit Slack:
> After a brief look at the spec, the empty string hash case doesn't seem to be explicitly talked about, but I don't see a reason here why we shouldn't match behavior of other major browsers. Could you file a bug on https://bugs.webkit.org about this?
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Radar WebKit Bug Importer
<rdar://problem/85356188>
Sam Sneddon [:gsnedders]
From Kate:
> After a brief look at the spec, the empty string hash case doesn't seem to be explicitly talked about, but I don't see a reason here why we shouldn't match behavior of other major browsers.
That implies per spec that the empty string is just another string, no? If it isn't special-cased, then it's just another length of string, hence this is both "match the spec and match other browsers".
(Also a WPT test for this would be nice, if there isn't already one!)
Matthew Finkel
Pull request: https://github.com/webkit/WebKit/pull/2526
Matthew Finkel
Wrote this a few weeks ago, finally got around to posting it.
Matthew Finkel
And, because I didn't actually say this in the previous comment:
This bug is not present in trunk. It was (possibly accidentally) fixed as part of https://bugs.webkit.org/show_bug.cgi?id=235199
Canonical link: https://commits.webkit.org/246139@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@288132 268f45cc-cd09-0410-ab3c-d52691b4dbfc
The PR is adding a WPT test, as Sam suggested.
Matthew Finkel
I hacked at export-w3c-test-changes and got it to create a PR.
https://github.com/web-platform-tests/wpt/pull/34902
EWS
Committed 255611@main (2142cd8c9e15): <https://commits.webkit.org/255611@main>
Reviewed commits have been landed. Closing PR #2526 and removing active labels.