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
Hide nonce
content attribute values. (#2369)
#2373
Changes from 1 commit
e1fe3e9
7c2ecca
5fce306
84e0e9b
51e0a2a
ba33b18
0eccfe5
218badf
c8f5419
1a78955
67f38c6
d628a08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6839,6 +6839,56 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute | |
</ol> | ||
</div> | ||
|
||
<h4>Nonce attributes</h4> | ||
|
||
<p>A <dfn data-export="">nonce content attribute</dfn> represents a cryptographic nonce ("number | ||
used once") which can be used by <cite>Content Security Policy</cite> to determine whether or not | ||
a given fetch will be allowed to proceed. The value is text. <ref spec="CSP"></p> | ||
|
||
<p>Elements that have a <span>nonce content attribute</span> 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 name <dfn data-export="" | ||
data-dfn-for="NoncedHTMLElement" data-dfn-type="attribute">[[CryptographicNonce]]</dfn>, and | ||
exposing it to script via the <code>NoncedHTMLElement</code> interface defined below:</p> | ||
|
||
<pre class="idl">[NoInterfaceObject] | ||
interface <dfn>NoncedHTMLElement</dfn> { | ||
[<span>CEReactions</span>] attribute DOMString nonce; | ||
};</pre> | ||
|
||
<dl class="domintro"> | ||
<dt><var>element</var> . <code data-x="">nonce</code></dt> | ||
<dd> | ||
<p>Returns the value of the element's <code>[[CryptographicNonce]]</code> internal slot.</p> | ||
<p>Can be set, to update that slot's value.</p> | ||
</dd> | ||
</dl> | ||
|
||
<p>The <dfn><code data-x="dom-NoncedHTMLElement-nonce">nonce</code></dfn> IDL attribute must, on | ||
getting, return the value of the element's <code>[[CryptographicNonce]]</code>; and on setting, | ||
set the element's <code>[[CryptographicNonce]]</code> to the specified new value.</p> | ||
|
||
<p>When such an element that implements <code>NoncedHTMLElement</code> <span>becomes | ||
connected</span>, the user agent must <span>immediately</span> execute the following steps on the | ||
<var>element</var>: | ||
|
||
<ol> | ||
<li> | ||
<p>If <var>element</var> has a <span>nonce content attribute</span> <var>attr</var> whose value | ||
is not the empty string, then:</p> | ||
|
||
<ol> | ||
<li>Let <var>nonce</var> be <var>attr</var>'s value.</li> | ||
<li>Set <var>attr</var>'s value to the empty string.</li> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the initial value in this slot, if any? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's say the empty string. |
||
<li>Set <var>element</var>.<code>[[CryptographicNonce]]</code> to <var>nonce</var>.</li> | ||
</ol> | ||
</li> | ||
</ol> | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does this need [CEReactions]? But see below. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you're right; this attribute is unnecessary in the model we're working with here. |
||
<p>The <span data-x="concept-node-clone-ext">cloning steps</span> for elements that implement | ||
<code>NoncedHTMLElement</code> must set the <code>[[CryptographicNonce]]</code> slot on the copy | ||
to the value of the slot on the element being cloned.</p> | ||
|
||
|
||
<h3>Common DOM interfaces</h3> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So if you do this on an element with a "nonce" attribute before it's been inserted into the DOM, it won't return anything useful, right? Is that the behavior we want? Similarly, if you set this on an element before it's inserted into the DOM, what happens? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's the way things are written right now, yes. I think what you're implying is that we might want to change the mechanism to trigger when attributes are appended, changed, or replaced? We can explore that, but it's not really clear to me what the mechanism would look like. Here, we have an attribute on the element, and we reset it's value upon insertion, which has pretty clearly defined behaviors. If we alter the above algorithms, what visible behavior would you expect from
Assuming something like:
I'd expect the inserted element to have its There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
No, I'm implying that the One think that's not clear to me: in current UAs if you have a
What about the same case but that sets both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That seems more confusing than just treating them as separate things. I think I'd prefer the currently described behavior.
You mean something like the following?
If so, no, it doesn't. Skimming https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp?rcl=ded5e27012a9b0d50de4b80a16e024fe5106b160&l=65, I think Blink will potentially trigger a load upon parsing
I don't have strong feelings about this. If you'd like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Would not execute, as the internal slot would be overwritten with the incorrect value at insertion time. The order of the assignement to |
||
|
||
|
@@ -12839,7 +12889,6 @@ interface <dfn>HTMLLinkElement</dfn> : <span>HTMLElement</span> { | |
[<span>CEReactions</span>] attribute <span>RequestDestination</span> <span data-x="dom-link-as">as</span>; // (default "") | ||
[SameObject, PutForwards=<span data-x="dom-DOMTokenList-value">value</span>] readonly attribute <span>DOMTokenList</span> <span data-x="dom-link-relList">relList</span>; | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-link-media">media</span>; | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-link-nonce">nonce</span>; | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-link-integrity">integrity</span>; | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-link-hreflang">hreflang</span>; | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-link-type">type</span>; | ||
|
@@ -12849,7 +12898,9 @@ interface <dfn>HTMLLinkElement</dfn> : <span>HTMLElement</span> { | |
[<span>CEReactions</span>] attribute <span>WorkerType</span> <span data-x="dom-link-workertype">workerType</span>; | ||
[<span>CEReactions</span>] attribute boolean <span data-x="dom-link-useCache">useCache</span>; | ||
}; | ||
<span>HTMLLinkElement</span> implements <span>LinkStyle</span>;</pre> | ||
<span>HTMLLinkElement</span> implements <span>LinkStyle</span>; | ||
<span>HTMLLinkElement</span> implements <span>NoncedHTMLElement</span>; | ||
</pre> | ||
</dd> | ||
</dl><!--TOPIC:HTML--> | ||
|
||
|
@@ -12865,6 +12916,10 @@ interface <dfn>HTMLLinkElement</dfn> : <span>HTMLElement</span> { | |
<span>CORS settings attribute</span>. It is intended for use with <span data-x="external resource | ||
link">external resource links</span>.</p> | ||
|
||
<p>The <dfn><code data-x="attr-link-nonce">nonce</code></dfn> attribute is a <span>nonce content | ||
attribute</span>. It is intended for use with <span data-x="external resource link">external | ||
resource links</span>.</p> | ||
|
||
<p>The types of link indicated (the relationships) are given by the value of the <dfn><code | ||
data-x="attr-link-rel">rel</code></dfn> attribute, which, if present, must have a value that is a | ||
<span>set of space-separated tokens</span>. The <a href="#linkTypes">allowed keywords and their | ||
|
@@ -12956,11 +13011,6 @@ interface <dfn>HTMLLinkElement</dfn> : <span>HTMLElement</span> { | |
<p>The <dfn><code data-x="attr-link-media">media</code></dfn> attribute says which media the | ||
resource applies to. The value must be a <span>valid media query list</span>.</p> | ||
|
||
<p>The <dfn><code data-x="attr-link-nonce">nonce</code></dfn> attribute represents a cryptographic | ||
nonce ("number used once") which can be used by <cite>Content Security Policy</cite> to determine | ||
whether or not an <span data-x="external resource link">external resource specified by the | ||
link</span> will be loaded and applied to the document. The value is text. <ref spec="CSP"></p> | ||
|
||
<p>The <dfn data-export="" data-dfn-for="link" data-dfn-type="element-attr"><code | ||
data-x="attr-link-integrity">integrity</code></dfn> attribute represents the <span | ||
data-x="concept-request-integrity-metadata">integrity metadata</span> for requests which this | ||
|
@@ -13078,7 +13128,6 @@ interface <dfn>HTMLLinkElement</dfn> : <span>HTMLElement</span> { | |
<dfn><code data-x="dom-link-hreflang">hreflang</code></dfn>, | ||
<dfn><code data-x="dom-link-integrity">integrity</code></dfn>, | ||
<dfn><code data-x="dom-link-media">media</code></dfn>, | ||
<dfn><code data-x="dom-link-nonce">nonce</code></dfn>, | ||
<dfn><code data-x="dom-link-rel">rel</code></dfn>, | ||
<dfn><code data-x="dom-link-scope">scope</code></dfn>, | ||
<dfn><code data-x="dom-link-sizes">sizes</code></dfn>, and | ||
|
@@ -13220,8 +13269,8 @@ interface <dfn>HTMLLinkElement</dfn> : <span>HTMLElement</span> { | |
<span>environment settings object</span>. | ||
|
||
<li><p>Set <var>request</var>'s <span data-x="concept-request-nonce-metadata">cryptographic | ||
nonce metadata</span> to the current value of the <code>link</code> element's <code | ||
data-x="attr-link-nonce">nonce</code> content attribute.</p></li> | ||
nonce metadata</span> to the current value of the <code>link</code> element's | ||
<code>[[CryptographicNonce]]</code> internal slot.</p></li> | ||
|
||
<li><p>Set <var>request</var>'s <span data-x="concept-request-integrity-metadata">integrity | ||
metadata</span> to the current value of the <code>link</code> element's <code | ||
|
@@ -14559,10 +14608,10 @@ people expect to have work and what is necessary. | |
<pre class="idl">[<span>HTMLConstructor</span>] | ||
interface <dfn>HTMLStyleElement</dfn> : <span>HTMLElement</span> { | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-style-media">media</span>; | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-style-nonce">nonce</span>; | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-style-type">type</span>; | ||
}; | ||
<span>HTMLStyleElement</span> implements <span>LinkStyle</span>;</pre> | ||
<span>HTMLStyleElement</span> implements <span>LinkStyle</span>; | ||
<span>HTMLStyleElement</span> implements <span>NoncedHTMLElement</span>;</pre> | ||
</dd> | ||
</dl><!--TOPIC:HTML--> | ||
|
||
|
@@ -14605,10 +14654,8 @@ interface <dfn>HTMLStyleElement</dfn> : <span>HTMLElement</span> { | |
attribute is omitted, is "<code data-x="">all</code>", meaning that by default styles apply to all | ||
media.</p> | ||
|
||
<p>The <dfn><code data-x="attr-style-nonce">nonce</code></dfn> attribute represents a | ||
cryptographic nonce ("number used once") which can be used by <cite>Content Security Policy</cite> | ||
to determine whether or not the style specified by an element will be applied to the document. The | ||
value is text. <ref spec="CSP"></p> | ||
<p>The <dfn><code data-x="attr-style-nonce">nonce</code></dfn> attribute is a <span>nonce content | ||
attribute</span>.</p> | ||
|
||
<p id="title-on-style">The <dfn><code data-x="attr-style-title">title</code></dfn> attribute on | ||
<code>style</code> elements defines <span data-x="CSS style sheet set">CSS style sheet | ||
|
@@ -14783,8 +14830,7 @@ c-end = "-->"</pre> | |
|
||
<div w-nodev> | ||
|
||
<p>The <dfn><code data-x="dom-style-media">media</code></dfn>, <dfn><code | ||
data-x="dom-style-nonce">nonce</code></dfn>, and <dfn><code | ||
<p>The <dfn><code data-x="dom-style-media">media</code></dfn>, and <dfn><code | ||
data-x="dom-style-type">type</code></dfn> IDL attributes must <span>reflect</span> the respective | ||
content attributes of the same name.</p> | ||
|
||
|
@@ -57540,10 +57586,10 @@ interface <dfn>HTMLScriptElement</dfn> : <span>HTMLElement</span> { | |
[<span>CEReactions</span>] attribute boolean <span data-x="dom-script-defer">defer</span>; | ||
[<span>CEReactions</span>] attribute DOMString? <span data-x="dom-script-crossOrigin">crossOrigin</span>; | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-script-text">text</span>; | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-script-nonce">nonce</span>; | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-script-integrity">integrity</span>; | ||
|
||
};</pre> | ||
}; | ||
<span>HTMLScriptElement</span> implements <span>NoncedHTMLElement</span>;</pre> | ||
</dd> | ||
</dl><!--TOPIC:HTML--> | ||
|
||
|
@@ -57690,9 +57736,8 @@ interface <dfn>HTMLScriptElement</dfn> : <span>HTMLElement</span> { | |
data-x="CORS protocol">CORS protocol</span> for cross-origin fetching.</p> | ||
|
||
<p>The <dfn data-export="" data-dfn-for="script" data-dfn-type="element-attr"><code | ||
data-x="attr-script-nonce">nonce</code></dfn> attribute represents a cryptographic nonce ("number | ||
used once") which can be used by <cite>Content Security Policy</cite> to determine whether or not | ||
the script specified by an element will be executed. The value is text. <ref spec="CSP"></p> | ||
data-x="attr-script-nonce">nonce</code></dfn> attribute is a <span>nonce content | ||
attribute</span>.</p> | ||
|
||
<p>The <dfn data-export="" data-dfn-for="script" data-dfn-type="element-attr"><code | ||
data-x="attr-script-integrity">integrity</code></dfn> attribute represents the <span | ||
|
@@ -57717,10 +57762,9 @@ interface <dfn>HTMLScriptElement</dfn> : <span>HTMLElement</span> { | |
<p>The IDL attributes <dfn><code data-x="dom-script-src">src</code></dfn>, <dfn><code | ||
data-x="dom-script-type">type</code></dfn>, <dfn><code | ||
data-x="dom-script-charset">charset</code></dfn>, <dfn><code | ||
data-x="dom-script-defer">defer</code></dfn>, <dfn><code | ||
data-x="dom-script-integrity">integrity</code></dfn>, and <dfn><code | ||
data-x="dom-script-nonce">nonce</code></dfn>, must each <span>reflect</span> the respective | ||
content attributes of the same name.</p> | ||
data-x="dom-script-defer">defer</code></dfn>, and <dfn><code | ||
data-x="dom-script-integrity">integrity</code></dfn>, must each <span>reflect</span> the | ||
respective content attributes of the same name.</p> | ||
|
||
<p>The <dfn><code data-x="dom-script-crossOrigin">crossOrigin</code></dfn> IDL attribute must | ||
<span>reflect</span> the <code data-x="attr-script-crossorigin">crossorigin</code> content attribute.</p> | ||
|
@@ -58219,14 +58263,8 @@ o............A....e | |
</dl> | ||
</li> | ||
|
||
<li> | ||
|
||
<p>If the <code>script</code> element has a <code data-x="attr-script-nonce">nonce</code> | ||
attribute, then let <var>cryptographic nonce</var> be that attribute's value.</p> | ||
|
||
<p>Otherwise, let <var>cryptographic nonce</var> be the empty string.</p> | ||
|
||
</li> | ||
<li><p>Let <var>cryptographic nonce</var> be the element's <code>[[CryptographicNonce]]</code> | ||
internal slot's value.</p></li> | ||
|
||
<li> | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have mutation observer tests for this behavior? This is a little different from the parser modifying the value directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, is the nonce likely shared across elements? If so, we should maybe hide it for all elements including those that do not yet implement
NoncedHTMLElement
. Otherwise each time we add it to a new element you might end up having it accidentally exposed in user agents that do not implement that new nonce feature yet.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In which case it should maybe be part of DOM's "superglobal" (not named as such) attributes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, but I can add some to web-platform-tests/wpt#5423.
I'm happy to do it that way, it's probably more future-proof. Also, I'm told that Firefox actually implements nonces for more resource types than we've actually specced, so doing it at a higher level is probably helpful for them in the short term.
In that case, would you suggest dropping
NoncedHTMLElement
, and putting the behavior onHTMLElement
directly?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, though if you also want to add it to SVG (for
<svg:script>
and friends) we should maybe just put it on Element.(I didn't realize the observable mutation of the nonce content attribute was intentional. I guess it doesn't matter much as we also expose it through the
nonce
IDL attribute.)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do indeed want to apply the same change to
SVGScriptElement
.Element
sounds like the simplest way to do that.It's "intentional" only insofar as it seems a necessary side-effect of tying the adjustment to insertion. I suppose we could avoid it by hooking more deeply into the mechanics of setting the attribute's value via something like
setAttribute
, but it doesn't seem like a good idea to introduce that kind of complexity.Since we're really only concerned about hiding the value from non-script sources, that seems like a reasonable tradeoff.