Closed Bug 1374612 Opened 5 years ago Closed 2 years ago

CSP: Hide nonce values from the DOM

Categories

(Core :: DOM: Security, defect, P1)

defect

Tracking

()

RESOLVED FIXED
mozilla75
Tracking Status
firefox75 --- fixed

People

(Reporter: ckerschb, Assigned: ckerschb)

References

(Blocks 1 open bug)

Details

(Keywords: dev-doc-complete, Whiteboard: [domsecurity-active])

Attachments

(1 file)

Prevent nonce exfiltration via CSS selectors and similar tricks. By hiding the nonce from the DOM those kind of CSP policy bypasses can be prevented.

See also:
https://github.com/whatwg/html/pull/2373
https://github.com/w3c/web-platform-tests/tree/master/content-security-policy/nonce-hiding
Blocks: csp-w3c-3
Priority: -- → P3
Whiteboard: [domsecurity-backlog1]
Depends on: 1389421

Hi,

The change described in the original report (hiding nonces attribute values) has been merged on Nov 22, 2017 but this does not seem to be addressed yet.

Are there any plans to do so? :)

We briefly discussed this at TPAC. Do you may have an ETA for this? :)

Duplicate of this bug: 1612923
Keywords: dev-doc-needed
Assignee: nobody → ckerschb
Status: NEW → ASSIGNED
Priority: P3 → P1
Whiteboard: [domsecurity-backlog1] → [domsecurity-active]
Duplicate of this bug: 1389421
Pushed by nbeleuzu@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/59fe98b41d80
CSP: Hide nonce values from the DOM. r=smaug
Backout by dluca@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/62f803edfb19
Backed out changeset 59fe98b41d80 for WPT failures in /html/dom/idlharness.https.html. CLOSED TREE

(In reply to Pulsebot from comment #8)

Backout by dluca@mozilla.com:

Thanks - I am on it!

Flags: needinfo?(ckerschb)
Pushed by shindli@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/ec4c2b2a561b
CSP: Hide nonce values from the DOM. r=smaug
Backout by shindli@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/eb328df4c35f
Backed out changeset ec4c2b2a561b for causing wpt permafails in /html/dom/reflection-metadata.html CLOSED TREE

(In reply to Pulsebot from comment #12)

Backout by shindli@mozilla.com:

Rrrrrh - again? On it ...

Flags: needinfo?(ckerschb)
Pushed by csabou@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/190ac0f2afb3
CSP: Hide nonce values from the DOM. r=smaug,annevk
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla75

Note that the intersection of this bug and https://bugzilla.mozilla.org/show_bug.cgi?id=1446231 might lead to a compatibility issue for Web Extensions. We got a report from a user that our Web Extension was broken on Firefox Beta, and it turned out to be due to this change—we were only using getAttribute to propogate nonce values. While Chrome has implemented nonce-hiding for a while, it also implemented a more general CSP bypass for script nodes injected by extensions, so we only ever implemented the getAttribute route and were broken by this change. Is there a way for Firefox to lessen this breakage (in my opinion, the ideal way is to implement 1446231), or at the very least, can this rate a mention in the WebExtension or Security changelogs?

Also, smaller thing, but it looks like https://github.com/mdn/browser-compat-data/blob/master/api/HTMLElement.json wasn't updated for this change, so it still shows the .nonce API as unsupported on Firefox. I don't know the process by which this gets updated, but it seems like that should happen here?

Flags: needinfo?(ckerschb)

(In reply to nightpool from comment #16)

Note that the intersection of this bug and https://bugzilla.mozilla.org/show_bug.cgi?id=1446231 might lead to a compatibility issue for Web Extensions. We got a report from a user that our Web Extension was broken on Firefox Beta, and it turned out to be due to this change—we were only using getAttribute to propogate nonce values. While Chrome has implemented nonce-hiding for a while, it also implemented a more general CSP bypass for script nodes injected by extensions, so we only ever implemented the getAttribute route and were broken by this change. Is there a way for Firefox to lessen this breakage (in my opinion, the ideal way is to implement 1446231), or at the very least, can this rate a mention in the WebExtension or Security changelogs?

Anne, Smaug, Kris, what's your take? With our current way of implementing the nonce hiding, I don't think adding carve-outs is easily doable. Any thoughts?

Flags: needinfo?(kmaglione+bmo)
Flags: needinfo?(ckerschb)
Flags: needinfo?(bugs)
Flags: needinfo?(annevk)

nightpool, did you try setting 'strict-dynamic' in your web extensions' CSP in Firefox? I think that should give you nonce propagation implicitly.

Flags: needinfo?(eg1290)

In our experience it's best to fix your Extension code (esp. if it was already working without any extra carve-outs in FF).
We usually recommend to retrieve CSP nonces in the following way which works in all browsers regardless if they're "nonce-hiding" or not:

var nonce = script['nonce'] || script.getAttribute('nonce');

(In reply to nightpool from comment #16)

Also, smaller thing, but it looks like https://github.com/mdn/browser-compat-data/blob/master/api/HTMLElement.json wasn't updated for this change, so it still shows the .nonce API as unsupported on Firefox. I don't know the process by which this gets updated, but it seems like that should happen here?

That kind of update doesn't happen in bugs implementing features. (But I don't know how it happens)

Flags: needinfo?(bugs)

(In reply to Frederik Braun [:freddy] from comment #18)

nightpool, did you try setting 'strict-dynamic' in your web extensions' CSP in Firefox? I think that should give you nonce propagation implicitly.

The problem is not my web extension's CSP, it's the CSP of the page that hosts the content script, which we can't control. To inject any other script nodes onto the page, we have to retrieve the nonce from a script on the page and then add it to the script we're injecting. So we were doing something like const nonce = document.querySelector("[nonce]").find(script => script.getAttribute("nonce")), and then adding that to the inline scripts we injected onto the page.

(In reply to Lukas Weichselbaum from comment #19)

In our experience it's best to fix your Extension code (esp. if it was already working without any extra carve-outs in FF).
We usually recommend to retrieve CSP nonces in the following way which works in all browsers regardless if they're "nonce-hiding" or not:

var nonce = script['nonce'] || script.getAttribute('nonce');

Yes, we implemented this as a workaround, but because the page's CSP only affects content scripts in Firefox, my guess is that there are lots of content scripts out there that don't have this code in them already. Like I said, ultimately I think the underlying bug here is that Firefox subjects script nodes inserted by content scripts to the same CSP as they're inserted on, which is both a worse experience for developers and different from how Chrome does it.

Ultimately, I don't have any way to quantify this breakage, and it seems like we're too late in the cycle to get https://bugzilla.mozilla.org/show_bug.cgi?id=1446231 implemented for Firefox 75, but it feels like at least a release note or something is warranted.

Flags: needinfo?(eg1290)

Update to MDN is tracked by the dev-doc-needed keyword. Adding this to release notes seems reasonable, but I don't think we should provide a special extensions code path for this given they can use the IDL attribute.

Flags: needinfo?(annevk)

(In reply to Olli Pettay [:smaug] from comment #20)

(In reply to nightpool from comment #16)

Also, smaller thing, but it looks like https://github.com/mdn/browser-compat-data/blob/master/api/HTMLElement.json wasn't updated for this change, so it still shows the .nonce API as unsupported on Firefox. I don't know the process by which this gets updated, but it seems like that should happen here?

That kind of update doesn't happen in bugs implementing features. (But I don't know how it happens)

I've created https://github.com/mdn/browser-compat-data/pull/5888 for this.

Also now announced on Firefox 75 for developers:
https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/75#Security

And documented in the reference:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/nonce

Who can review this?

Looks mostly accurate. I updated https://wiki.developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/75 as we already supported the nonce attribute. It mainly applies to more elements now and the content attribute is hidden from script (the IDL attribute isn't, perhaps obviously).

Florian, I think per nightpool's request we should also add a note to "Changes for add-on developers" in that nonce hiding might affect them and that any .getAttribute("nonce") call they have probably needs to become a .nonce get.

I updated https://wiki.developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/75 as we already supported the nonce attribute. It mainly applies to more elements now and the content attribute is hidden from script (the IDL attribute isn't, perhaps obviously).

Great, thank you! Do you know when .nonce landed initially? I thought this bug implemented it and so this PR https://github.com/mdn/browser-compat-data/pull/5888 sets the compat data for it to Firefox 75, but if it in fact was available earlier, I'd like to know when.

Florian, I think per nightpool's request we should also add a note to "Changes for add-on developers" in that nonce hiding might affect them and that any .getAttribute("nonce") call they have probably needs to become a .nonce get.

I've added it to the add-ons section as well.

(In reply to Florian Scholz [:fscholz] (MDN) from comment #25)

Great, thank you! Do you know when .nonce landed initially? I thought this bug implemented it and so this PR https://github.com/mdn/browser-compat-data/pull/5888 sets the compat data for it to Firefox 75, but if it in fact was available earlier, I'd like to know when.

This was clarified. Initial .nonce support happened in this bug as .nonce didn't land earlier in bug 1389421 (was backed out).

I've mentioned this now twice on https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/75
(in the security section and in the section for add-on devs)

Reference page updates on https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/nonce and now also on https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute to refer to use .nonce instead .getAttribute("nonce")

Compat table will be updated later this week when https://github.com/mdn/browser-compat-data/pull/5888 makes it to MDN prod.

Calling this complete for now. Please let me know if there is anything else here in terms of docs.

I think you want bug 1446231.

Flags: needinfo?(kmaglione+bmo)
You need to log in before you can comment on or make changes to this bug.