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

Re: CSP script hashes

From: Bryan McQuade <bmcquade@google.com>
Date: Tue, 12 Feb 2013 12:50:31 -0500
Message-ID: <CADLGQyAPbCaQEHndULNLRL67L2LbY5taYCoU42mEfT1y_o0ATg@mail.gmail.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" <public-webappsec@w3.org>
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 17:51:03 GMT

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