13
<?php
header("Content-Security-Policy: default-src 'sha256-".base64_encode(hash('sha256', 'console.log("Hello world");', true))."'");
?>
<script>console.log("Hello world");</script>

However I still receive in Chrome:

Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'sha256-1DCfk1NYWuHM8DgTqlkOta97gzK+oBDDv4s7woGaPIY='". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.

I've toyed with this for over an hour but still am unable to generate a hash that matches examples eg.

http://software-security.sans.org/downloads/appsec-2014-files/building-a-content-security-policy-csp-eric-johnson.pdf Claims <script>alert('Allowed to execute');</script> (hard to determine original spacing) has hash of sha256-MmM3YjgyNzI5MDc5NTA0ZTdiCWViZGExZDkxMDhlZWIw NDIwNzU2YWE5N2E4YWRjNWQ0ZmEyMDUyYjVkNjE0NTk=

Which doesn't make much sense: the last part doesn't start with sha256-, but at least the first hash is the correct length. I get sha256-nbFv/38jW7zf8mQirwFemFjDwp5CwIaorxe4Z3yycn0= as the hash for alert('Allowed to execute');

http://nmatatal.blogspot.com/2013/09/how-my-script-hash-poc-works.html Claims: <script>console.log("Hello world");</script> should have a csp of script-src 'sha256-y/mJvKQC/3H1UwsYAtTR7Q==' eyeballing it, that looks too short.


What am I doing wrong?

alexmuller
  • 1,061
  • 1
  • 9
  • 13
Steven R.
  • 417
  • 1
  • 3
  • 7
  • Hey, wanted to follow up on the link referenced. sha256 isn't supported, just sha1. I think the value would be fU8Y3i83rje0823mI+3hgmqgysc= but I haven't tested. Updated the docs accordingly and that link now points to a blog using script hash. – oreoshake Aug 23 '14 at 21:20
  • For anybody stumbling here with my same problem, it seems that Chrome calculates hashes using Unix newlines, not Windows new lines. – GGGforce Mar 08 '21 at 14:56

3 Answers3

10

This is still incredibly confusing. I'm running Chrome 40 and like you I've just spent far longer than I would have liked figuring out what's going on.

The CSP 2 spec says this about hashing <script> elements:

For example, the SHA-256 digest of alert('Hello, world.'); is YWIzOWNiNzJjNDRlYzc4MTgwMDhmZDlkOWI0NTAyMjgyY2MyMWJlMWUyNjc1ODJlYWJhNjU5MGU4NmZmNGU3OAo=.

I've managed to generate that hash by running:

$ echo -n "alert('Hello, world.');" | openssl dgst -sha256 | base64
YWIzOWNiNzJjNDRlYzc4MTgwMDhmZDlkOWI0NTAyMjgyY2MyMWJlMWUyNjc1ODJlYWJhNjU5MGU4NmZmNGU3OAo=

But this does not work in Chrome 40.

The editor's draft of CSP says this:

For example, the SHA-256 digest of alert('Hello, world.'); is qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng=.

The example they give is generated with:

$ echo -n "alert('Hello, world.');" | openssl dgst -sha256 -binary | base64
qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng=

The addition of the -binary flag to openssl is the difference between the two commands.

This does work in Chrome 40 (stable) and Chrome Canary, but I believe it still has issues in Firefox 36.

alexmuller
  • 1,061
  • 1
  • 9
  • 13
  • This commit makes it seem like the first hash was never correct: https://github.com/w3c/webappsec/commit/19b3773c51465fd2ea32f6e0be7b39325a949b89 – alexmuller Jan 31 '15 at 19:48
  • 1
    It gets worse :) -- Firefox will write a warning to the console and POST a violation report even if the correct hash is provided. See https://bugzilla.mozilla.org/show_bug.cgi?id=1128195 for more details. – Eric Rath Jul 06 '15 at 21:54
4

UPDATE: it seems script hashes are not supported in the Chrome release version. My test only works in Chrome Canary (when using script-src, not default-src)

——

You should try using "script-src" instead of "default-src" (based on my quick reading of the working draft)

Joel L
  • 1,427
  • 11
  • 12
  • This is the test page that works in Chrome Canary: http://pastebin.com/2pnT728f – Joel L May 27 '14 at 12:38
  • I actually switched from script-src to default-src because it wasn't working for me. Your update makes sense why neither was working for me. – Steven R. May 28 '14 at 10:40
  • I read the draft but wasn't sure how to treat proceeding and trailing whitespace in ` – Steven R. May 28 '14 at 10:42
0

https://security.stackexchange.com/a/34998/41628

So it looks that all you have to do (for the time being, until Chrome updates to reflect the status change of the CSP 1.1 proposal) is, to change the header name back to X-Content-Security-Policy.

Steven R.
  • 417
  • 1
  • 3
  • 7