- From: Brian Smith <brian@briansmith.org>
- Date: Wed, 5 Nov 2014 18:48:16 -0800
- To: "public-webappsec@w3.org" <public-webappsec@w3.org>
- Message-ID: <CAFewVt4fqUuz-eQMUdSg_rG8xyShJXdAGmwaO=i=77S=y=e_og@mail.gmail.com>
Hi, I noticed that the current draft says this about nonces: "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. This requirement ensures that the nonce-value is difficult for an attacker to predict." I have one suggestion, one annoying comment, and one question regarding this: Suggestion: I think it would be useful to suggest that the nonce be generated with a cryptographically secure random number generator, and that the nonce be at least 128-bits long, before base64 encoding. Although obvious to all of us, I suspect that many people trying to use nonces will not have the background to create a proper nonce. Annoying Comment: "nonce" is not a great name for this construct, because technically the requirements for a CSP nonce are greater than the requirements for a nonce in normal usage of that word. But, it seems to be too late to change this. Question: Are the current requirements on nonces sufficient to ensure safe usage? I can think of three cases that make me think CSP nonce is not as secure as I would expect, but I think I may be overlooking something important: Case 1. Imagine that the web page contains a CSP nonce of X. Further, assume that the page uses XHR to retrieve HTML fragments from a server, and then inserts those fragments into the document. Further, assume that an attacker learns the value X (because CSP doesn't require X to be secret), and then inserts <script nonce=X> into that fragment retrieved via XHR. It seems like the attacker's XSS will succeed, despite CSP. It seems to me that it would be good to restrict CSP nonce so that it only works on static <script> elements, not on dynamically inserted ones, to avoid this, but I don't see that in the spec. Case 2: Imagine that the web page contains a CSP nonce of Y. Further, imagine that the web page is dynamically generated and that the server sends the headers and the first part of the page. Further, imagine that the second part of the page is dynamically generated and contains user-generated content from a database. If an attacker can learn the value Y between the time it is generated and the time when all the dynamic elements of the page have been built, it would be possible for the attacker to use a stored XSS attack to insert <script nonce=Y> into the second part of the page. It seems like it is important to recommend that the server not transmit any part of a response that uses script-nonce until the whole response page has been generated, and more generally require the server to not otherwise reveal the nonce value before the page is generated. Again, this is the kind of requirement that is common for cryptographic protocols, but which would be easy for a typical user of CSP to overlook, so explicitly suggesting this would be useful for ensuring safe(r) use of this construct. Case 3: A variation of Case 2. IIUC, it seems to me like violation reports transmit the violated directive and the whole policy. It seems like the nonce would be included at least once in the violation report. It would be amusing if an attacker could force a violation report to be sent before the page was finished loading, causing the browser to send the the violation report containing the nonce to the server, causing the server to insert the violation report into a database accessible to an attacker, where the attacker read the violation report from the database and used it to build an XSS that gets included in the page, because the page wasn't fully generated before the browser sent the violation report. Again, I'm not very familiar with CSP nonce, so I'm likely overlooking something that invalidates the concerns in cases 1-3, but I cannot figure out what it is. Help? Thanks, Brian
Received on Thursday, 6 November 2014 02:48:44 UTC