- From: Neil Matatall <neilm@twitter.com>
- Date: Thu, 19 Sep 2013 15:46:07 -0700
- To: "public-webappsec@w3.org" <public-webappsec@w3.org>
Sorry for the long period of silence, I've been doing some evangelizing. Script hashes will be another source expression. Per script hash, the algorithm and digest length precede the actual hash value. e.g.: script-src 'sha256-0byNO6Svx+EJYSy3Osvd2sBSyTAlqh+ClC7au33rgqE' If a script hash source is specified and the user agent understands it, the browser should ignore the 'unsafe-inline' directive for backwards compatibility. Any inline script whose computed hash value does not match a hash specified in the hash sources should not be executed and an informative error message should be displayed including the expected hash value. If multiple hashing algorithms are specified in the CSP header, the browser must compute all possible hashes for each inline script block. If the computed hash matches any computed hash in the header with a matching algorithm+digest length, the script should execute. There was talk of limiting this to one algorithm per header, but CDNs complicate things. This is not meant to and should not support dynamic javascript. Hashes should not be computed dynamically (at least not in production). === Computing hash values base64encode(<hashing algorithm>(UTF-8(<content of script tag>))) <script> alert(1); </script> base64encode(sha256(UTF-8("\n alert(1);\n"))) === Script-hash unobtrusive workflow (PoC) Unfortunately, many online hashing services will strip leading/trailing whitespace which is not what we want. I wrote a quick and dirty method for computing all script-hashes on a page: $.each($('script'), function(index, x) { console.log(CryptoJS.SHA256(x.innerHTML).toString(CryptoJS.enc.Base64)); }); Here's the equivilent openssl command: openssl dgst -sha256 -binary | base64 I wrote a more thorough rails plugin and explained how it works in [1] including a (low quality) video on how the developer workflow would work: [2]. Essentially: 1) Find all inline scripts - search through the source code of any file that could be rendered / displayed to a user. 2) Extract the content of each inline script, hash according to the algo above. 3) Store as Filename -> [hashes] mapping. In a configuration file, for example. 4) Any time a file is rendered, the corresponding hashes are added to the CSP header. I believe this can be built in to every framework and be unobtrusive. [1] http://nmatatal.blogspot.com/2013/09/how-my-script-hash-poc-works.html [2] http://www.youtube.com/watch?v=Bc2hvziTRxg p.s. I support both script nonce and script hash, I think we need to have both :-/
Received on Thursday, 19 September 2013 22:46:34 UTC