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

Re: [CSP] Clarifications on nonces

From: Brian Smith <brian@briansmith.org>
Date: Thu, 6 Nov 2014 16:24:59 -0800
Message-ID: <CAFewVt5A=SC=aVSAor9DGCj48HJ=Vi++AERHbdwO2R0hozzfSQ@mail.gmail.com>
To: Devdatta Akhawe <dev.akhawe@gmail.com>
Cc: "public-webappsec@w3.org" <public-webappsec@w3.org>
Devdatta Akhawe <dev.akhawe@gmail.com> wrote:
> Re the remaining two issues:  I am wondering if this is getting really
> into esoteric territory now. Can you give an example of a server-side
> XSS attack that could occur because the page wasn't fully generated
> before the nonce was sent out to the client? I say server-side because
> I agree with you that it would be nice to be able to lock down the
> nonce to only work before DOMContentLoaded fires.

Let's first read what the spec says: "If the policy contains a
nonce-source expression, the server MUST generate a fresh value for
the nonce-value directive at random and independently each time it
transmits a policy."

Now, let's boil down what this means, literally:

1. Server generates nonce.
2. Server transmits the policy to the client along with all HTTP headers.

At this point, the server has fulfilled its requirements to protect
the nonce, according to the above text. Therefore, it no longer is
obligated to hide the nonce from an attacker.

3. Server gives the attacker the nonce X.
4. Attacker performs some stored XSS attack where they insert <script nonce=X>.
5. Server generates the HTML for the response, incorporating the
stored XSS with <script nonce=X>
6. Server transmits the HTML containing the stored XSS attack to the browser.
7. Browser accepts the attacker's <script nonce=X>.

Now, obviously it would be dumb to just hand the nonce to the
attacker, at any point in time. But, I don't think that any of us
expect the attacker to be unable to learn X forever. So, I think we
agree that there must be some point in time between when the server
transmits the policy to the client, and the end of the universe, at
which it is safe for the attacker to learn what the nonce is. I think
the spec should specify that point in time, because it is important.

For example, this is what NIST SP800-38a [1] says about IV generation
for the CBC mode of encryption: "For the CBC and CFB modes, the IVs
must be unpredictable. In particular, for any given plaintext, it must
not be possible to predict the IV that will be associated to the
plaintext in advance of the generation of the IV." In other words, it
is saying that a CBC mode IV needs to be secret until after the
attacker gives you the plaintext to encrypt. (The assumption is a
chosen-plaintext attack.)

I believe CSP nonce is similar (XSS is also a chosen-plaintext attack)
and that means that the spec should say that the nonce needs to be
hidden from the attacker until after the attacker has given the server
all the XSS to incorporate into the document. The new rules for CSP
nonce that I suggested (which are the same or similar to the ones
suggested by Dev) follow from this.

Unfortunately, there is rarely an explicit "gather all the XSS attacks
to incorporate into the response" step for serving a web page. Due to
poor planning in most web frameworks, the gathering of XSS attacks is
usually spread across many different parts of the page generation
process. Therefore, it seems like a good idea to keep the nonce secret
until the entire response generation process is complete. That would
imply, in particular, that the Content-Security-Policy header and any
part of the response body should not be transmitted to the client
until page generation is complete. (This is similar to how we do
things for CBC cipher suites in TLS 1.1; we encrypt an entire TLS
record before transmitting the IV.)

Cheers,
Brian

[1] http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
Received on Friday, 7 November 2014 00:25:27 UTC

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