Signatur
Beschreibung
Die Eigenschaft nonce stammt aus dem Mixin HTMLOrSVGElement. Deshalb gibt es sie auf HTMLElement und auf SVGElement gleichermaßen. Sie spiegelt die Nonce wider, die im Inhaltsattribut nonce steht. Eine Content Security Policy (CSP) mit einer Direktive wie script-src 'nonce-abc123' lässt Inline-Skripte und -Styles nur dann zu, wenn ihre Nonce mit dem Wert aus der Richtlinie übereinstimmt.
Relevant ist das vor allem für SVG-eigene <script>- und <style>-Elemente, also Elemente im Namensraum http://www.w3.org/2000/svg. Wenn Sie solche Elemente zur Laufzeit erzeugen, müssen Sie ihnen die gültige Nonce der Seite mitgeben. Sonst blockiert die CSP sie.
Wichtig ist das Nonce-Hiding. Wird die CSP per HTTP-Header ausgeliefert, leert der Browser das Inhaltsattribut, sobald das Element in das Dokument eingefügt ist. getAttribute('nonce') liefert dann einen leeren String, und auch CSS-Attributselektoren sehen den Wert nicht mehr. Nur die IDL-Eigenschaft element.nonce enthält noch die echte Nonce. So soll verhindert werden, dass die Nonce über CSS-Seitenkanäle abfließt.
Beispiele
Nonce eines bestehenden SVG-Skripts auslesen
// HTML: <svg id="logo"><script nonce="r4nd0m">/* ... */</script></svg>
// CSP-Header: Content-Security-Policy: script-src 'nonce-r4nd0m'
const svgScript = document.querySelector('#logo script');
console.log(svgScript instanceof SVGElement);
console.log(svgScript.nonce); // IDL-Eigenschaft
console.log(svgScript.getAttribute('nonce')); // Attribut (durch Nonce-Hiding geleert)
SVG-Skript zur Laufzeit mit gültiger Nonce einfügen
const SVG_NS = 'http://www.w3.org/2000/svg';
// Nonce von einem vertrauenswürdigen, bereits vorhandenen Skript übernehmen
const pageNonce = document.querySelector('script[nonce]')?.nonce ?? '';
const svg = document.createElementNS(SVG_NS, 'svg');
const script = document.createElementNS(SVG_NS, 'script');
script.nonce = pageNonce; // ohne Nonce würde die CSP das Skript blockieren
script.textContent = "console.log('SVG-Skript ausgeführt');";
svg.append(script);
document.body.append(svg);
Inline-Style in SVG mit style-src-Nonce
const SVG_NS = 'http://www.w3.org/2000/svg';
const nonce = document.querySelector('style[nonce], script[nonce]')?.nonce ?? '';
const svg = document.createElementNS(SVG_NS, 'svg');
svg.setAttribute('viewBox', '0 0 100 100');
const style = document.createElementNS(SVG_NS, 'style');
style.nonce = nonce;
style.textContent = '.punkt { fill: tomato; }';
const circle = document.createElementNS(SVG_NS, 'circle');
circle.setAttribute('class', 'punkt');
circle.setAttribute('cx', '50');
circle.setAttribute('cy', '50');
circle.setAttribute('r', '40');
svg.append(style, circle);
document.body.append(svg);
console.log(style.nonce === nonce);
// Wichtig · Fallstricke
- Nonce-Hiding: Lesen Sie die Nonce immer über
element.nonceaus, nicht übergetAttribute('nonce'). Nach dem Einfügen ins Dokument ist das Attribut bei einer per Header ausgelieferten CSP leer. - Sicherheit: Eine Nonce muss für jede Antwort neu, zufällig und nicht erratbar erzeugt werden, empfohlen sind mindestens 128 Bit. Eine statische Nonce entwertet die CSP komplett. Geben Sie die Nonce niemals an nicht vertrauenswürdigen Code oder an Inhalte aus Nutzereingaben weiter. Wer die Nonce kennt, kann eigene Skripte einschleusen (XSS).
- Die Nonce allein schützt nicht vor gefährlichem Inhalt. Wird
textContenteines Skripts mit Nutzerdaten befüllt, bleibt es trotz CSP eine XSS-Lücke. - SVG-Elemente müssen mit
document.createElementNS()und dem SVG-Namensraum erzeugt werden.document.createElement('script')liefert einHTMLScriptElement, keinSVGScriptElement. - Die Nonce wirkt nur, wenn die CSP sie per
'nonce-…'erlaubt. Mit'strict-dynamic'dürfen Skripte, die ein vertrauenswürdiges Skript nachlädt, auch ohne eigene Nonce laufen. - Kompatibilität: Ältere Browser, etwa Firefox vor Version 75, kennen die Eigenschaft auf
SVGElementnicht. Dort hilft als ErsatzsetAttribute('nonce', wert)vor dem Einfügen.