Reputation: 203
I can not get whitelisting by checksum to work in firefox (52.0.2, windows). Firefox supports content security policy version 2 according to caniuse, so checksumming should be supported.
When chrome blocks an inline script, it prints the needed sha-256 to console. Adding it to the csp rules successfully whitelists the script. The checksum is also identical to the one calculated at https://report-uri.io/home/hash
But firefox refuse to accept it.
I noted that the example in the MDN docs is using base-16 as opposed to base-64 encoding for the checksum. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
But even with the MDN example I get the same results. (Also chrome rejects with the base-16 encoding). I tried a bunch of variations on the following:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
content="script-src 'sha256-076c8f1ca6979ef156b510a121b69b6265011597557ca2971db5ad5a2743545f'">
<title>Hello CSP</title>
</head>
<body>
<script type="text/javascript">var inline = 1;</script>
</body>
</html>
Content Security Policy: The page’s settings blocked the loading of a resource at self (“script-src 'sha256-076c8f1ca6979ef156b510a121b69b6265011597557ca2971db5ad5a2743545f'”). Source: var inline = 1;.
Upvotes: 13
Views: 21466
Reputation: 18398
Update Aug 22nd 2022 - Bug was filed in bugzilla https://bugzilla.mozilla.org/show_bug.cgi?id=1785871 and it looks like the fix is in draft state
Ran into this today. What's happening is it seems Firefox only supports base64 url-safe encodings while chrome is more permissive.
From the w3c spec: https://w3c.github.io/webappsec-csp/#framework-directive-source-list
Note: The base64-value grammar allows both base64 and base64url encoding. These encodings are treated as equivalent when processing hash-source values. Nonces, however, are strict string matches: we use the base64-value grammar to limit the characters available, and reduce the complexity for the server-side operator (encodings, etc), but the user agent doesn’t actually care about any underlying value, nor does it do any decoding of the nonce-source value.
Technically browsers are supposed to support both. This is why mdemonic's answer seems to do something.
I've highlighted this to Firefox folks. We'll see if something changes here!
Conclusion: when you're making CSP hashes - use the base64 url-safe variant. If it doesn't work in chrome, use both the unsafe and safe variants.
Upvotes: 1
Reputation: 203
I couldn't put this one completely to rest since there was obviously something strange and confusing going on. And I discovered something interesting:
+
with -
, and each /
with _
.Voila! You have a checksum that works with Chrome but not Firefox. Judging by the Base64 variants, this format is not unreasonable.
It turns out that the Dartium browser, based on Chrome 45, emits the checksum in the "alternative format," which is likely how it got onto my clipboard.
This only works with Chrome:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'sha256-LqkgOOr2rKDFd7Yl4hZ4H8nB0Stbc-RDo573pA7E/XU='">
<title>Hello CSP</title>
<script type="text/javascript">alert("running");</script>
</head>
</html>
Upvotes: 7
Reputation: 87984
It will work if you change the hash value as in the following:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
content="script-src 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='">
<title>Hello CSP</title>
</head>
<body>
<script type="text/javascript">var inline = 1;</script>
</body>
</html>
Not sure why you were seeing the behavior in Chrome you describe; when I test the example in the question in Chrome, it blocks the script and emits an error message saying to use the hash value sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8=
.
And https://report-uri.io/home/hash also outputs that value when given var inline = 1;
.
Upvotes: 7