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

Re: Updated script hash proposal (non spec text)

From: Neil Matatall <neilm@twitter.com>
Date: Fri, 20 Sep 2013 09:46:07 -0700
Message-ID: <CAOFLtbjSXQXh7x8FosD2Bvk6qZ2crrWSJ=09KV0n6Ua-D86ktw@mail.gmail.com>
To: Mountie Lee <mountie@paygate.net>
Cc: "public-webappsec@w3.org" <public-webappsec@w3.org>
> 1. what to do after comparing hash?

The policy used determines this, it will generate a warning and
optionally block depending on the presence of "-Report-Only" in the
header name.

> 2. page encodings

There has definitely been some discussion on this. ABarth explained
this one time but I _think_ the consensus that UTF-8 only was OK. All
valid javascript code characters fall within UTF-8 and non-UTF-8 data
can be read from elsewhere in the DOM/external scripts. I would
definitely appreciate extra eyes on this. It breaks some edge cases
(like script A modifying script B before B is done loading), but still
works in the common case.

> 3. add tag attributes to hash source

I don't think this gives us any benefit and increases the complexity
of the hashing significantly. There was talk of including the "type"
attribute, but I believe that was decided to be ignored. Type
"application/json" is ignored by CSP enforcement, VBScript/Ruby/Etc
are not covered by this.

On Fri, Sep 20, 2013 at 12:21 AM, Mountie Lee <mountie@paygate.net> wrote:
> questions and comments.
>
> 1. what to do after comparing hash?
>
> if browser calculate and compare the script hash,
> what to do next? block? warning? get user consent?
> dependent on browser vendor decision?
>
> 2. page encodings
>
> scripts are dependent on page encodings.
> many countries use non unicode encoding (GB2312, BIG5, EUC-KR, EUC-JP,
> Shift-JIS)
>
> is the non-unicode page encodings out of scope?
> can we use "charset" attribute in script tag?
>
> 3. add tag attributes to hash source
>
> in your example,
> <script>
>   alert(1);
> </script>
>
> "\n  alert(1);\n" is the hash source.
>
> if the tag has more attributes like
> <script language="javascript" charset="EUC-KR">
>  alert(1);
> </script>
>
> can we add tag attributes ("language...." part) to hash source?
>
>
>
> On Fri, Sep 20, 2013 at 7:46 AM, Neil Matatall <neilm@twitter.com> 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 :-/
>>
>
>
>
> --
> Mountie Lee
>
> PayGate
> CTO, CISSP
> Tel : +82 2 2140 2700
> E-Mail : mountie@paygate.net
>
> =======================================
> PayGate Inc.
> THE STANDARD FOR ONLINE PAYMENT
> for Korea, Japan, China, and the World
>
Received on Friday, 20 September 2013 16:46:35 UTC

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