- From: Brian Smith <brian@briansmith.org>
- Date: Thu, 6 Nov 2014 16:24:59 -0800
- 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