Google Chrome Stripping nonce values from script tags Google Chrome Stripping nonce values from script tags google-chrome google-chrome

Google Chrome Stripping nonce values from script tags


What’s described in the question is actually expected behavior — required per the HTML spec:

https://html.spec.whatwg.org/multipage/#nonce-attributes:attr-nonce

Elements that have a nonce content attribute ensure that the crytographic nonce is only exposed to script (and not to side-channels like CSS attribute selectors) by extracting the value from the content attribute, moving it into an internal slot named [[CryptographicNonce]]

https://html.spec.whatwg.org/multipage/#nonce-attributes:dom-noncedelement-nonce

…the setter for the nonce IDL attribute does not update the corresponding content attribute. This, as well as the below setting of the nonce content attribute to the empty string when an element becomes browsing-context connected, is meant to prevent exfiltration of the nonce value through mechanisms that can easily read content attributes, such as selectors.

This behavior was added in an update to the spec at https://github.com/whatwg/html/pull/2373 (Hide nonce content attribute values); see675 https://github.com/whatwg/html/issues/2369.

To be clear: the behavior the spec requires is, if the markup source you serve over the wire has:

<script nonce=DhcnhD3khTMePgXw>...</script>

…then if you open browser devtools and use the DOM inspector, what you’ll see instead is this:

<script nonce>...</script>

That is, the DOM inspector will show no value for the nonce attribute on that script element.

More accurately: you’ll see no value for the nonce attribute on that script if the doc is served with a Content-Security-Policy header, and the browser is applying the policy in that header.

If you don’t serve the doc with a Content-Security-Policy header, or browsers don’t apply the policy from it, you’ll see nonce=DhcnhD3khTMePgXw for the script element in the inspector.

So the lack of a value for that nonce attribute in the DOM inspector actually indicates that things are working as expected. That is, it indicates the browser is checking the value for a match against any nonce-* source expressions in the Content-Security-Policy header.

The way it works inside browsers is: browsers move the nonce attribute’s value to an “internal slot” for the browser’s own use. So it stays available to the browser, but hidden from the DOM.

The reason you don’t yet see the same behavior as Chrome’s in Safari is, Safari hasn’t caught up with the spec update and implemented the requirement. But there is an open Safari bug.


To check if your browser conforms to the spec behavior, you can use the tests here:

And the current results for those tests in major browsers are here: