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

Re: CSP script hashes

From: Nicholas Green <ngreen@twitter.com>
Date: Tue, 12 Feb 2013 12:01:22 -0800
Message-ID: <CADYSid9tVfSHQN8n1bAWzwBusJg+mZssnBNDiGjDh05aXua3rQ@mail.gmail.com>
To: Bryan McQuade <bmcquade@google.com>
Cc: Ian Melven <imelven@mozilla.com>, Jacob Hoffman-Andrews <jsha@twitter.com>, Eric Chen <eric.chen@sv.cmu.edu>, "public-webappsec@w3.org" <public-webappsec@w3.org>, Yoav Weiss <yoav@yoav.ws>
Thanks for the awesome summary Bryan.  Pretty much agree across the board.

On Tue, Feb 12, 2013 at 11:41 AM, Bryan McQuade <bmcquade@google.com> wrote:
> On Tue, Feb 12, 2013 at 2:23 PM, Ian Melven <imelven@mozilla.com> wrote:
>>
>>
>> Hi,
>>
>> >  Supported algorithms can be added/removed in new versions of CSP.
>>
>> i'm not sure about removing supported algorithms from new versions of CSP,
>> won't this break sites
>> who use those algorithms and haven't updated yet ? ie their hashes won't
>> work so their scripts
>> won't be inlined, which will likely break the site.
>
>
> The only reason I can think of to remove an algo is when it's been shown to
> be insecure/breakable. Jacob mentioned this earlier: "Allowing server to
> choose is good future-proofing in case one of the hash algorithms is broken
> in the future." I don't know if an algorithm would actually be removed in
> this case but it's an option. Adam and Mike may have thoughts here.
>
>>
>>
>> as far as this piece :
>>
>> "Should dynamic creation of script elements that match the hash, e.g. with
>> document.write(), be allowed or is the policy only evaluated on the first
>> pass of the input stream preprocessor and new inline script nodes prohibited
>> thereafter? " Proposal: prohibit dynamic addition of inline script blocks.
>> Can anyone think of a reason that it would be problematic to prohibit
>> dynamic addition of inline script blocks?"
>>
>> what is the rationale for preventing this beyond difficulty of
>> implementation ?
>
>
> I suppose it could be argued that there is a marginally larger attack
> surface and that it's difficult to predict server side what the hash of
> dynamic script blocks is going to be. If you know the hash for a dynamic
> script block when the response is generated on the server, then why not just
> include the code directly in the HTML? If the block should be executed
> dynamically then add the logic to determine if it should run in the script
> block that was served in the HTML. The only case I can think of where it
> might be necessary to dynamically insert a script block is if you have other
> JS on the page that is looking things up by finding e.g. the first/last
> script block in the DOM (or by some other identification mechanism). I
> suppose it is possible but uncommon.
>
> All that said, I don't feel strongly one way or another here. So far it
> sounds like we have one suggestion to block dynamically inserted inline
> script blocks and another to treat them the same as any other inline script
> block (i.e. execute them if they match a hash in the CSP header). What do
> others think?

One benefit I see to preventing dynamically injected scripts from
running is slightly more control over when and how many times a script
is run.  At least a DOM XSS can no longer re-execute a whitelisted
script.  That said -- it seems unlikely that re-running a script
that's explicitly whitelisted would be of great use to an attacker.

So I don't see a benefit to allowing dynamically injected <script>
tags.  Rather than injecting a script tag from JS one could just
execute JS, so I see nothing problematic about prohibiting dynamic
addition of inline script blocks.  On the other hand I don't see a
major risk allowing these scripts to run either, no strong opinion.

However, I'm curious if the same can be said for <style> blocks.  I
have seen cases where an inline <style> block is added to a page via
JS.  That said: in these situations the injected CSS is usually not
known at page load (or it would've been set from the start), thus the
whitelist approach can't help us as the CSP header is of course are
already set when the JS creates and injects the <style> tag.   But
there may well be cases where JS is choosing which style block to add
to a page between a handful of options, where we might be able to
whitelist those options server side.  Not sure this is a valid use
case though, curious for thoughts on it.

>
>>
>>
>> thanks,
>> ian
>>
>>
>> ----- Original Message -----
>> From: "Bryan McQuade" <bmcquade@google.com>
>> To: "Yoav Weiss" <yoav@yoav.ws>
>> Cc: "Jacob Hoffman-Andrews" <jsha@twitter.com>, "Eric Chen"
>> <eric.chen@sv.cmu.edu>, "Nicholas Green" <ngreen@twitter.com>,
>> public-webappsec@w3.org
>> Sent: Tuesday, February 12, 2013 9:50:31 AM
>> Subject: Re: CSP script hashes
>>
>>
>> Great, thanks everyone for the feedback. To summarize:
>>
>>
>> We see value in being able to choose the hashing algorithm on the server.
>> Jacob notes: " Allowing server to choose is good future-proofing in case one
>> of the hash algorithms is broken in the future. " Mountie notes that wee
>> should use "recognized algorithm names" from
>> http://www.w3.org/TR/WebCryptoAPI/#recognized-algorithm-name . Proposal:
>> server must state the hashing algorithm used, and we require support for
>> 'SHA-1' and 'SHA-256' algorithms. Supported algorithms can be added/removed
>> in new versions of CSP.
>>
>>
>> Hashes should be base64 encoded in the CSP header.
>>
>>
>> We will not support transmission of partial hashes to allow servers to
>> trade security for number of bytes on the wire. Supporting partial hashes
>> adds complexity to the protocol and weakens security, so not a good idea.
>> The server can use the existing 'unsafe-inline' if they do not want fully
>> secure inline scripts/styles, else they must use full hashes.
>>
>>
>> There is some concern about the size of hashes on the wire. However most
>> pages should have only a few inline blocks so this is likely not an issue in
>> practice. Jacob suggests computing a single hash of all inline blocks but
>> Yoav points out correctly that this would break streaming HTML parsing,
>> which is important. Proposal: each block will need its own hash value in the
>> CSP header.
>>
>>
>> There was some discussion about hashing attributes of the script tag. Brad
>> Hill suggested including the attributes in the hash. My proposal is to not
>> do this. CSP for external scripts does not provide any provisions for
>> whitelisting/blacklisting based on script attributes. For consistency, I
>> propose not including attributes in the inline hash computation either.
>> Mountie Lee suggested including hashes inline on script tag attributes but
>> an attacker could modify these if they have access to the response body so
>> this does not seem desirable. Proposal: hashes go in the CSP response
>> header, and hashes are computed based on the contents of script/style blocks
>> only, and not based on the script/style block attributes.
>>
>>
>> I had suggested allowing side-effects such as document.written inline
>> scripts to be whitelisted, but I had not thought this through fully. I no
>> longer believe that we should whitelist document.written inline scripts.
>> Brad Hill commented: " Should dynamic creation of script elements that match
>> the hash, e.g. with document.write(), be allowed or is the policy only
>> evaluated on the first pass of the input stream preprocessor and new inline
>> script nodes prohibited thereafter? " Proposal: prohibit dynamic addition of
>> inline script blocks. Can anyone think of a reason that it would be
>> problematic to prohibit dynamic addition of inline script blocks?
>>
>>
>> I'm going to start a separate thread about handling character encodings,
>> etc when computing hashes client-side, since this seems to be the place
>> where the majority of complexity and uncertainty remains. A separate
>> discussion to focus on those issues is needed.
>>
>>
>>
>>
>> On Tue, Feb 12, 2013 at 4:17 AM, Yoav Weiss < yoav@yoav.ws > wrote:
>>
>>
>>
>>
>>
>> I support moving forward with hashes to allow inline styles and scripts. I
>> believe they'd be much easier to deploy than nonces in many scenarios, which
>> will eventually mean increased security.
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> What about having a single inline-hash that is a digest of all allowed
>> inline content in the document, including both styles and scripts? The
>> browser would maintain a running digest as it encounters each style or
>> script tag. Once the digest matches the allowed inline-hash the browser
>> would execute the content immediately, or would report a violation upon
>> reaching the end of the document without ever matching the hash.
>>
>>
>> This makes it harder to deploy pages that dynamically include from
>> multiple sources, but keeps things simple and saves bytes.
>>
>>
>>
>>
>> That would mean the browser cannot start executing inline scripts & styles
>> until the entire HTML has been downloaded (or at the very least, the last
>> inlined resource). Even for static HTMLs with multiple inlined resources,
>> this can result in a significant slowdown of the page load without any
>> benefit. (saving 30 bytes on the response headers doesn't seem like a
>> significant benefit)
>>
>>
>> Yoav
>>
>>
>>
>>
>
Received on Tuesday, 12 February 2013 20:04:11 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Tuesday, 12 February 2013 20:04:12 GMT