W3C home > Mailing lists > Public > public-webappsec@w3.org > November 2013

Re: Updated script hash proposal (non spec text)

From: Neil Matatall <neilm@twitter.com>
Date: Mon, 25 Nov 2013 10:24:48 -0800
Message-ID: <CAOFLtbiJk3F+t1+6+RC_L=7qWHgNksgA05=ebsc66s2f1SWuKQ@mail.gmail.com>
To: Garrett Robinson <grobinson@mozilla.com>
Cc: "public-webappsec@w3.org" <public-webappsec@w3.org>
Ah yes. Oops. I support the second option as well.

Should "1*( ALPHA / DIGIT / "+" / "/" / "=" )"  be its own
symbol/definition/whatever to make it clear that the values will have the
same rules?


On Fri, Nov 22, 2013 at 3:52 PM, Garrett Robinson <grobinson@mozilla.com>wrote:

> This proposal (and the now-implemented proposal to extend the allowed
> characters in nonce-source to encompass base64 [0]) need clarification on
> handling '=', commonly used for padding base64. This character is not
> required for decoding, but is commonly added by base64 encoders.
>
> I am concerned that users will use techniques like the ones described in
> this proposal under "Computing hash values" and Script-hash unobtrusive
> workflow", both of which cause "=" to be appended, and will incorrectly
> have their hashes rejected if "=" isn't considered a valid character (which
> is the case for the current different of nonce-source, for example).
>
> I believe this could also be a concern for users of nonce-source, who I
> imagine will probably use a technique similar to:
>
> head -c 16 /dev/urandom | base64
>
> to generate their nonces, which will also have '=' appended for padding.
>
> There are two options here: we can either tell implementers to strip the
> unnecessary ='s from their nonces and hashes, or include them in the
> definition of valid nonce-/hash-sources. I prefer the second option for
> simplicity.
>
> A patch to update the ABNF definitions in the spec is attached.
>
> [0] http://lists.w3.org/Archives/Public/public-webappsec/2013Jun/0123.html
>
>
> On 09/19/2013 03:46 PM, Neil Matatall wrote:
>
>> 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 Monday, 25 November 2013 18:25:19 UTC

This archive was generated by hypermail 2.3.1 : Monday, 23 October 2017 14:54:03 UTC