diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/content-security-policy/nonce-hiding | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/content-security-policy/nonce-hiding')
8 files changed, 568 insertions, 0 deletions
diff --git a/testing/web-platform/tests/content-security-policy/nonce-hiding/nonces.html b/testing/web-platform/tests/content-security-policy/nonce-hiding/nonces.html new file mode 100644 index 0000000000..7ee10a7b29 --- /dev/null +++ b/testing/web-platform/tests/content-security-policy/nonce-hiding/nonces.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> + const namespace_url= { + "HTML": "http://www.w3.org/1999/xhtml", + "SVG": "http://www.w3.org/2000/svg", + } + const test_cases = [ + ["meh" , "HTML"], + ["div" , "HTML"], + ["script" , "HTML"], + ["meh" , "SVG"], + ["svg" , "SVG"], + ["script" , "SVG"], + ]; + + test_cases.forEach(([localName, namespace]) => { + test(t => { + const element = document.createElementNS(namespace_url[namespace], localName); + t.add_cleanup(() => element.remove()); + assert_equals(element.nonce, "", "Initial IDL attribute value"); + assert_equals(element.getAttribute("nonce"), null, "Initial content attribute"); + + element.setAttribute("nonce", "x"); + assert_equals(element.nonce, "x", "IDL attribute is modified after content attribute set"); + assert_equals(element.getAttribute("nonce"), "x", "Content attribute is modified after content attribute set"); + + document.body.appendChild(element); + assert_equals(element.nonce, "x", "IDL attribute is unchanged after element insertion"); + assert_equals(element.getAttribute("nonce"), "", "Content attribute is changed after element insertion"); + }, `Basic nonce tests for ${localName} in ${namespace} namespace`); + + test(t => { + const element = document.createElementNS(namespace_url[namespace], localName); + t.add_cleanup(() => element.remove()); + element.setAttribute("nonce", "x"); + assert_equals(element.nonce, "x", "IDL attribute is modified after content attribute set"); + + element.removeAttribute("nonce"); + assert_equals(element.nonce, "", "IDL attribute is empty after content attribute removal"); + }, `Ensure that removal of content attribute does not affect IDL attribute for ${localName} in ${namespace} namespace`); + + test(t => { + const element = document.createElementNS(namespace_url[namespace], localName); + t.add_cleanup(() => element.remove()); + assert_equals(element.nonce, ""); + assert_equals(element.getAttribute("nonce"), null); + + element.setAttribute("nonce", ""); + assert_equals(element.nonce, ""); + assert_equals(element.getAttribute("nonce"), ""); + + document.body.appendChild(element); + assert_equals(element.nonce, ""); + assert_equals(element.getAttribute("nonce"), ""); + + element.removeAttribute("nonce"); + assert_equals(element.nonce, ""); + assert_equals(element.getAttribute("nonce"), null); + }, `Test empty nonces for ${localName} in ${namespace} namespace`); + }); +</script> diff --git a/testing/web-platform/tests/content-security-policy/nonce-hiding/nonces.html.headers b/testing/web-platform/tests/content-security-policy/nonce-hiding/nonces.html.headers new file mode 100644 index 0000000000..daf482b5ab --- /dev/null +++ b/testing/web-platform/tests/content-security-policy/nonce-hiding/nonces.html.headers @@ -0,0 +1 @@ +Content-Security-Policy: img-src 'none' diff --git a/testing/web-platform/tests/content-security-policy/nonce-hiding/script-nonces-hidden-meta.sub.html b/testing/web-platform/tests/content-security-policy/nonce-hiding/script-nonces-hidden-meta.sub.html new file mode 100644 index 0000000000..f8e5b946f0 --- /dev/null +++ b/testing/web-platform/tests/content-security-policy/nonce-hiding/script-nonces-hidden-meta.sub.html @@ -0,0 +1,131 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<meta http-equiv="content-security-policy" content="script-src 'nonce-abc'; img-src 'none'"> + +<body> +<!-- Basics --> +<script nonce="abc" id="testScript"> + document.currentScript.setAttribute('executed', 'yay'); +</script> + +<script nonce="abc"> + var script = document.querySelector('#testScript'); + + test(t => { + // Query Selector + assert_equals(document.querySelector('body [nonce]'), script); + assert_equals(document.querySelector('body [nonce=""]'), null); + assert_equals(document.querySelector('body [nonce=abc]'), script); + + assert_equals(script.getAttribute('nonce'), 'abc'); + assert_equals(script.nonce, 'abc'); + }, "Reading 'nonce' content attribute and IDL attribute."); + + // Clone node. + test(t => { + script.setAttribute('executed', 'boo'); + var s2 = script.cloneNode(); + assert_equals(s2.nonce, 'abc', 'IDL attribute'); + assert_equals(s2.getAttribute('nonce'), 'abc'); + }, "Cloned node retains nonce."); + + async_test(t => { + var s2 = script.cloneNode(); + document.head.appendChild(s2); + assert_equals(s2.nonce, 'abc'); + assert_equals(s2.getAttribute('nonce'), 'abc'); + window.addEventListener('load', t.step_func_done(_ => { + // The cloned script won't execute, as its 'already started' flag is set. + assert_equals(s2.getAttribute('executed'), 'boo'); + })); + }, "Cloned node retains nonce when inserted."); + + // Set the content attribute to 'foo' + test(t => { + script.setAttribute('nonce', 'foo'); + assert_equals(script.getAttribute('nonce'), 'foo'); + assert_equals(script.nonce, 'foo'); + }, "Writing 'nonce' content attribute."); + + // Set the IDL attribute to 'bar' + test(t => { + script.nonce = 'bar'; + assert_equals(script.nonce, 'bar'); + assert_equals(script.getAttribute('nonce'), 'foo'); + }, "Writing 'nonce' IDL attribute."); + + // Fragment parser. + var documentWriteTest = async_test("Document-written script executes."); + document.write(`<script nonce='abc'> + documentWriteTest.done(); + test(t => { + var script = document.currentScript; + assert_equals(script.getAttribute('nonce'), 'abc'); + assert_equals(script.nonce, 'abc'); + }, "Document-written script's nonce value."); + </scr` + `ipt>`); + + // Create node. + async_test(t => { + var s = document.createElement('script'); + s.innerText = script.innerText; + s.nonce = 'abc'; + assert_equals(s.nonce, 'abc'); + assert_equals(s.getAttribute('nonce'), null); + document.head.appendChild(s); + assert_equals(s.nonce, 'abc'); + assert_equals(s.getAttribute('nonce'), null); + + window.addEventListener('load', t.step_func_done(_ => { + assert_equals(s.getAttribute('executed'), 'yay'); + })); + }, "createElement.nonce."); + + async_test(t => { + var s = document.createElement('script'); + s.innerText = script.innerText; + s.nonce = 'zyx'; + s.setAttribute('nonce', 'abc'); + assert_equals(s.nonce, 'abc'); + document.head.appendChild(s); + assert_equals(s.nonce, 'abc'); + assert_equals(s.getAttribute('nonce'), 'abc'); + + window.addEventListener('load', t.step_func_done(_ => { + assert_equals(s.getAttribute('executed'), 'yay'); + })); + }, "setAttribute('nonce') overwrites '.nonce' upon insertion."); + + // Create node. + async_test(t => { + var s = document.createElement('script'); + s.innerText = script.innerText; + s.setAttribute('nonce', 'abc'); + assert_equals(s.getAttribute('nonce'), 'abc', "Pre-insertion content"); + assert_equals(s.nonce, 'abc', "Pre-insertion IDL"); + document.head.appendChild(s); + assert_equals(s.nonce, 'abc', "Post-insertion IDL"); + assert_equals(s.getAttribute('nonce'), 'abc', "Post-insertion content"); + + window.addEventListener('load', t.step_func_done(_ => { + assert_equals(s.getAttribute('executed'), 'yay'); + })); + }, "createElement.setAttribute."); +</script> + +<!-- CSS Leakage --> +<style> + #cssTest { display: block; } + #cssTest[nonce=abc] { background: url(/security/resources/abe.png); } +</style> +<script nonce="abc" id="cssTest"> + test(t => { + const script = document.querySelector('#cssTest'); + t.add_cleanup(() => script.remove()); + var style = getComputedStyle(script); + assert_equals(style['display'], 'block'); + assert_equals(style['background-image'], "url(\"http://{{domains[]}}:{{ports[http][0]}}/security/resources/abe.png\")"); + }, "Nonces leak via CSS side-channels."); +</script> diff --git a/testing/web-platform/tests/content-security-policy/nonce-hiding/script-nonces-hidden.html b/testing/web-platform/tests/content-security-policy/nonce-hiding/script-nonces-hidden.html new file mode 100644 index 0000000000..d9718d904c --- /dev/null +++ b/testing/web-platform/tests/content-security-policy/nonce-hiding/script-nonces-hidden.html @@ -0,0 +1,172 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js" nonce="abc"></script> +<script src="/resources/testharnessreport.js" nonce="abc"></script> + +<!-- `Content-Security-Policy: script-src 'nonce-abc'; img-src 'none'` delivered via headers --> + +<body> +<!-- Basics --> +<script nonce="abc" id="testScript"> + document.currentScript.setAttribute('executed', 'yay'); +</script> + +<script nonce="abc"> + var script = document.querySelector('#testScript'); + + test(t => { + // Query Selector + assert_equals(document.querySelector('body [nonce]'), script); + assert_equals(document.querySelector('body [nonce=""]'), script); + assert_equals(document.querySelector('body [nonce=abc]'), null); + + assert_equals(script.getAttribute('nonce'), ''); + assert_equals(script.nonce, 'abc'); + }, "Reading 'nonce' content attribute and IDL attribute."); + + // Clone node. + test(t => { + script.setAttribute('executed', 'boo'); + var s2 = script.cloneNode(); + assert_equals(s2.nonce, 'abc', 'IDL attribute'); + assert_equals(s2.getAttribute('nonce'), ''); + }, "Cloned node retains nonce."); + + async_test(t => { + var s2 = script.cloneNode(); + document.head.appendChild(s2); + assert_equals(s2.nonce, 'abc'); + assert_equals(s2.getAttribute('nonce'), ''); + + window.addEventListener('load', t.step_func_done(_ => { + // The cloned script won't execute, as its 'already started' flag is set. + assert_equals(s2.getAttribute('executed'), 'boo'); + })); + }, "Cloned node retains nonce when inserted."); + + // Set the content attribute to 'foo' + test(t => { + script.setAttribute('nonce', 'foo'); + assert_equals(script.getAttribute('nonce'), 'foo'); + assert_equals(script.nonce, 'foo'); + }, "Writing 'nonce' content attribute."); + + // Set the IDL attribute to 'bar' + test(t => { + script.nonce = 'bar'; + assert_equals(script.nonce, 'bar'); + assert_equals(script.getAttribute('nonce'), 'foo'); + }, "Writing 'nonce' IDL attribute."); + + // Fragment parser. + var documentWriteTest = async_test("Document-written script executes."); + document.write(`<script nonce='abc'> + documentWriteTest.done(); + test(t => { + var script = document.currentScript; + assert_equals(script.getAttribute('nonce'), ''); + assert_equals(script.nonce, 'abc'); + }, "Document-written script's nonce value."); + </scr` + `ipt>`); + + // Create node. + async_test(t => { + var s = document.createElement('script'); + s.innerText = script.innerText; + s.nonce = 'abc'; + assert_equals(s.nonce, 'abc'); + assert_equals(s.getAttribute('nonce'), null); + document.head.appendChild(s); + assert_equals(s.nonce, 'abc'); + assert_equals(s.getAttribute('nonce'), null); + + window.addEventListener('load', t.step_func_done(_ => { + assert_equals(s.getAttribute('executed'), 'yay'); + })); + }, "createElement.nonce."); + + async_test(t => { + var s = document.createElement('script'); + s.innerText = script.innerText; + s.nonce = 'zyx'; + s.setAttribute('nonce', 'abc'); + assert_equals(s.nonce, 'abc'); + document.head.appendChild(s); + assert_equals(s.nonce, 'abc'); + assert_equals(s.getAttribute('nonce'), ''); + + window.addEventListener('load', t.step_func_done(_ => { + assert_equals(s.getAttribute('executed'), 'yay'); + })); + }, "setAttribute('nonce') overwrites '.nonce' upon insertion."); + + // Create node. + async_test(t => { + var s = document.createElement('script'); + s.innerText = script.innerText; + s.setAttribute('nonce', 'abc'); + assert_equals(s.getAttribute('nonce'), 'abc', "Pre-insertion content"); + assert_equals(s.nonce, 'abc', "Pre-insertion IDL"); + document.head.appendChild(s); + assert_equals(s.nonce, 'abc', "Post-insertion IDL"); + assert_equals(s.getAttribute('nonce'), '', "Post-insertion content"); + + window.addEventListener('load', t.step_func_done(_ => { + assert_equals(s.getAttribute('executed'), 'yay'); + })); + }, "createElement.setAttribute."); +</script> + +<!-- Custom Element --> +<script nonce="abc"> + var eventList = []; + class NonceElement extends HTMLElement { + static get observedAttributes() { + return ['nonce']; + } + + constructor() { + super(); + } + + attributeChangedCallback(name, oldValue, newValue) { + eventList.push({ + type: "AttributeChanged", + name: name, + oldValue: oldValue, + newValue: newValue + }); + } + + connectedCallback() { + eventList.push({ + type: "Connected", + }); + } + } + + customElements.define("nonce-element", NonceElement); +</script> +<nonce-element nonce="abc"></nonce-element> +<script nonce="abc"> + test(t => { + assert_object_equals(eventList[0], { type: "AttributeChanged", name: "nonce", oldValue: null, newValue: "abc" }, "AttributeChanged 1"); + assert_object_equals(eventList[1], { type: "Connected" }, "Connected"); + assert_object_equals(eventList[2], { type: "AttributeChanged", name: "nonce", oldValue: "abc", newValue: "" }, "AttributeChanged 2"); + assert_equals(eventList.length, 3); + }, "Custom elements expose the correct events."); +</script> + +<!-- CSS Leakage --> +<style> + #cssTest { display: block; } + #cssTest[nonce=abc] { background: url(/security/resources/abe.png); } +</style> +<script nonce="abc" id="cssTest"> + test(t => { + const script = document.querySelector('#cssTest'); + t.add_cleanup(() => script.remove()); + var style = getComputedStyle(script); + assert_equals(style['display'], 'block'); + assert_equals(style['background-image'], 'none'); + }, "Nonces don't leak via CSS side-channels."); +</script> diff --git a/testing/web-platform/tests/content-security-policy/nonce-hiding/script-nonces-hidden.html.headers b/testing/web-platform/tests/content-security-policy/nonce-hiding/script-nonces-hidden.html.headers new file mode 100644 index 0000000000..ad8d0b54f3 --- /dev/null +++ b/testing/web-platform/tests/content-security-policy/nonce-hiding/script-nonces-hidden.html.headers @@ -0,0 +1 @@ +Content-Security-Policy: script-src 'nonce-abc'; img-src 'none' diff --git a/testing/web-platform/tests/content-security-policy/nonce-hiding/svgscript-nonces-hidden-meta.sub.html b/testing/web-platform/tests/content-security-policy/nonce-hiding/svgscript-nonces-hidden-meta.sub.html new file mode 100644 index 0000000000..870fef316e --- /dev/null +++ b/testing/web-platform/tests/content-security-policy/nonce-hiding/svgscript-nonces-hidden-meta.sub.html @@ -0,0 +1,100 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<meta http-equiv="content-security-policy" content="script-src 'nonce-abc'; img-src 'none'"> + +<body> +<!-- Basics --> +<svg xmlns="http://www.w3.org/2000/svg"> + <script nonce="abc" id="testScript"> + document.currentScript.setAttribute('executed', 'yay'); + </script> +</svg> + +<script nonce="abc"> + var script = document.querySelector('#testScript'); + + test(t => { + // Query Selector + assert_equals(document.querySelector('[nonce]'), script); + assert_equals(document.querySelector('[nonce=""]'), null); + assert_equals(document.querySelector('[nonce=abc]'), script); + + assert_equals(script.getAttribute('nonce'), 'abc'); + assert_equals(script.nonce, 'abc'); + }, "Reading 'nonce' content attribute and IDL attribute."); + + // Clone node. + test(t => { + script.setAttribute('executed', 'boo'); + var s2 = script.cloneNode(); + assert_equals(s2.nonce, 'abc', 'IDL attribute'); + assert_equals(s2.getAttribute('nonce'), 'abc'); + }, "Cloned node retains nonce."); + + async_test(t => { + var s2 = script.cloneNode(); + document.head.appendChild(s2); + assert_equals(s2.nonce, 'abc'); + assert_equals(s2.getAttribute('nonce'), 'abc'); + + window.addEventListener('load', t.step_func_done(_ => { + // The cloned script won't execute, as its 'already started' flag is set. + assert_equals(s2.getAttribute('executed'), 'boo'); + })); + }, "Cloned node retains nonce when inserted."); + + // Set the content attribute to 'foo' + test(t => { + script.setAttribute('nonce', 'foo'); + assert_equals(script.getAttribute('nonce'), 'foo'); + assert_equals(script.nonce, 'foo'); + }, "Writing 'nonce' content attribute."); + + // Set the IDL attribute to 'bar' + test(t => { + script.nonce = 'bar'; + assert_equals(script.nonce, 'bar'); + assert_equals(script.getAttribute('nonce'), 'foo'); + }, "Writing 'nonce' IDL attribute."); + + // Fragment parser. + var documentWriteTest = async_test("Document-written script executes."); + document.write(`<svg xmlns="http://www.w3.org/2000/svg"><script nonce='abc'> + documentWriteTest.done(); + test(t => { + var script = document.currentScript; + assert_equals(script.getAttribute('nonce'), 'abc'); + assert_equals(script.nonce, 'abc'); + }, "Document-written script's nonce value."); + </scr` + `ipt></svg>`); + + // Create node. + test(t => { + var s = document.createElement('svg'); + var innerScript = document.createElement('innerScript'); + innerScript.innerText = script.innerText; + innerScript.nonce = 'abc'; + s.appendChild(innerScript); + assert_equals(innerScript.nonce, 'abc'); + assert_equals(innerScript.getAttribute('nonce'), null, 'innerScript.getAttribute nonce'); + document.body.appendChild(s); + assert_equals(innerScript.nonce, 'abc'); + assert_equals(innerScript.getAttribute('nonce'), null, 'innerScript.getAttribute nonce'); + }, "createElement.nonce."); + + // Create node. + test(t => { + var s = document.createElement('svg'); + var innerScript = document.createElement('script'); + innerScript.innerText = script.innerText; + innerScript.setAttribute('nonce', 'abc'); + assert_equals(innerScript.getAttribute('nonce'), 'abc', "Pre-insertion content"); + assert_equals(innerScript.nonce, 'abc', "Pre-insertion IDL"); + s.appendChild(innerScript); + document.body.appendChild(s); + assert_equals(innerScript.nonce, 'abc', "Post-insertion IDL"); + assert_equals(innerScript.getAttribute('nonce'), 'abc', "Post-insertion content"); + }, "createElement.setAttribute."); +</script> diff --git a/testing/web-platform/tests/content-security-policy/nonce-hiding/svgscript-nonces-hidden.html b/testing/web-platform/tests/content-security-policy/nonce-hiding/svgscript-nonces-hidden.html new file mode 100644 index 0000000000..a50c75b34c --- /dev/null +++ b/testing/web-platform/tests/content-security-policy/nonce-hiding/svgscript-nonces-hidden.html @@ -0,0 +1,98 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js" nonce="abc"></script> +<script src="/resources/testharnessreport.js" nonce="abc"></script> + +<!-- `Content-Security-Policy: script-src 'nonce-abc'; img-src 'none'` delivered via headers --> + +<body> +<!-- Basics --> +<svg xmlns="http://www.w3.org/2000/svg"> + <script nonce="abc" id="testScript"> + document.currentScript.setAttribute('executed', 'yay'); + </script> +</svg> + +<script nonce="abc"> + var script = document.querySelector('#testScript'); + + test(t => { + // Query Selector + assert_equals(document.querySelector('body [nonce]'), script); + assert_equals(document.querySelector('body [nonce=""]'), script); + assert_equals(document.querySelector('body [nonce=abc]'), null); + + assert_equals(script.getAttribute('nonce'), ''); + assert_equals(script.nonce, 'abc'); + }, "Reading 'nonce' content attribute and IDL attribute."); + + // Clone node. + test(t => { + script.setAttribute('executed', 'boo'); + var s2 = script.cloneNode(); + assert_equals(s2.nonce, 'abc', 'IDL attribute'); + assert_equals(s2.getAttribute('nonce'), ''); + }, "Cloned node retains nonce."); + + async_test(t => { + var s2 = script.cloneNode(); + document.head.appendChild(s2); + assert_equals(s2.nonce, 'abc'); + assert_equals(s2.getAttribute('nonce'), ''); + + window.addEventListener('load', t.step_func_done(_ => { + // The cloned script won't execute, as its 'already started' flag is set. + assert_equals(s2.getAttribute('executed'), 'boo'); + })); + }, "Cloned node retains nonce when inserted."); + + // Set the content attribute to 'foo' + test(t => { + script.setAttribute('nonce', 'foo'); + assert_equals(script.getAttribute('nonce'), 'foo'); + assert_equals(script.nonce, 'foo'); + }, "Writing 'nonce' content attribute."); + + // Set the IDL attribute to 'bar' + test(t => { + script.nonce = 'bar'; + assert_equals(script.nonce, 'bar'); + assert_equals(script.getAttribute('nonce'), 'foo'); + }, "Writing 'nonce' IDL attribute."); + + // Fragment parser. + var documentWriteTest = async_test("Document-written script executes."); + document.write(`<svg xmlns="http://www.w3.org/2000/svg"><script nonce='abc'> + documentWriteTest.done(); + test(t => { + var script = document.currentScript; + assert_equals(script.getAttribute('nonce'), ''); + assert_equals(script.nonce, 'abc'); + }, "Document-written script's nonce value."); + </scr` + `ipt></svg>`); + + // Create node. + test(t => { + var s = document.createElement('svg'); + var innerScript = document.createElement('script'); + innerScript.innerText = script.innerText; + innerScript.nonce = 'abc'; + s.appendChild(innerScript); + document.body.appendChild(s); + assert_equals(innerScript.nonce, 'abc'); + assert_equals(innerScript.getAttribute('nonce'), null); + }, "createElement.nonce."); + + // Create node. + test(t => { + var s = document.createElement('svg'); + var innerScript = document.createElement('script'); + innerScript.innerText = script.innerText; + innerScript.setAttribute('nonce', 'abc'); + assert_equals(innerScript.getAttribute('nonce'), 'abc', "Pre-insertion content"); + assert_equals(innerScript.nonce, 'abc', "Pre-insertion IDL"); + s.appendChild(innerScript); + document.body.appendChild(s); + assert_equals(innerScript.nonce, 'abc', "Post-insertion IDL"); + assert_equals(innerScript.getAttribute('nonce'), '', "Post-insertion content"); + }, "createElement.setAttribute."); +</script> diff --git a/testing/web-platform/tests/content-security-policy/nonce-hiding/svgscript-nonces-hidden.html.headers b/testing/web-platform/tests/content-security-policy/nonce-hiding/svgscript-nonces-hidden.html.headers new file mode 100644 index 0000000000..ad8d0b54f3 --- /dev/null +++ b/testing/web-platform/tests/content-security-policy/nonce-hiding/svgscript-nonces-hidden.html.headers @@ -0,0 +1 @@ +Content-Security-Policy: script-src 'nonce-abc'; img-src 'none' |