Start · Sprachen · JavaScript · Referenz · HTMLElement.nonce

HTMLElement.nonce

Eigenschaft

Liest oder setzt die kryptografische Einmalnummer (Nonce), anhand derer eine Content Security Policy entscheidet, ob ein Skript oder Stylesheet ausgeführt bzw. angewendet werden darf.

seit JavaScript Baseline 2022 (Chrome 61+, Firefox 75+, Safari 15. Kategorie: webapi

Signatur

HTMLElement.nonce

Beschreibung

Die Eigenschaft nonce spiegelt das HTML-Attribut nonce wider. Es steht an Elementen wie <script>, <style> oder <link>. Eine Content Security Policy (CSP) mit einer Direktive wie script-src 'nonce-R4nd0m' lässt nur solche Inline-Skripte und externen Skripte zu, deren Nonce genau zum Wert aus dem Header passt. Laut Spezifikation kommt die Eigenschaft aus dem Mixin HTMLOrSVGElement. Sie gibt es deshalb auch bei SVGElement und MathMLElement.

Gebraucht wird nonce vor allem, wenn Sie Skripte oder Styles zur Laufzeit nachladen. Ein Element, das Sie mit document.createElement('script') erzeugen, hat zunächst keine Nonce und wird von einer strengen CSP blockiert. Bekommt es die Nonce eines vertrauenswürdigen, bereits laufenden Skripts, lässt der Browser es ausführen. Mit 'strict-dynamic' in der CSP ist diese Weitergabe sogar überflüssig, weil Skripte, die ein vertrauenswürdiges Skript per DOM-API einfügt, automatisch als vertrauenswürdig gelten.

Eine wichtige Besonderheit ist das Nonce-Hiding: Wird die CSP per HTTP-Header ausgeliefert, leert der Browser das Attribut, sobald das Element im Dokument steht. element.getAttribute('nonce') gibt dann "" zurück, und nur die IDL-Eigenschaft element.nonce liefert noch den echten Wert. So lässt sich die Nonce nicht über CSS-Attributselektoren (z. B. script[nonce^="a"]) auslesen und an Angreifer abfließen.

Wenn Sie element.nonce setzen, ändert sich nur der interne Wert und nicht das Attribut. Entscheidend ist, dass die Nonce gesetzt ist, bevor das Element ins Dokument eingefügt wird. Erst beim Einfügen prüft der Browser sie gegen die Richtlinie.

Parameter

Name Typ Default Beschreibung
$value string "" Nur beim Setzen: die Nonce als Zeichenkette, typischerweise Base64. Sie muss exakt dem Wert aus 'nonce-…' in der CSP entsprechen.

Rückgabewert

Typ
string
Beschreibung
Die aktuelle Nonce des Elements oder "", wenn keine gesetzt ist. Der Wert ist auch dann noch lesbar, wenn das Attribut durch Nonce-Hiding bereits geleert wurde.

Beispiele

Nonce an ein dynamisch nachgeladenes Skript weitergeben

// CSP-Header: Content-Security-Policy: script-src 'nonce-abc123XYZ'
// Das aktuell laufende Skript trägt bereits die gültige Nonce.
const trustedNonce = document.currentScript?.nonce ?? '';

const loadScript = (src) => new Promise((resolve, reject) => {
  const script = document.createElement('script');
  script.src = src;
  script.nonce = trustedNonce; // VOR dem Einfügen setzen!
  script.onload = resolve;
  script.onerror = reject;
  document.head.append(script);
});

await loadScript('/js/analytics.js');
console.log('Skript geladen, Nonce:', trustedNonce);
Skript geladen, Nonce: abc123XYZ

Nonce-Hiding: Attribut und Eigenschaft im Vergleich

// HTML: <script nonce="abc123XYZ" id="app">/* ... */</script>
// CSP wird per HTTP-Header ausgeliefert.
const el = document.getElementById('app');

console.log(el.getAttribute('nonce')); // Attribut wurde geleert
console.log(el.nonce);                 // IDL-Wert bleibt erhalten
console.log(el.hasAttribute('nonce')); // Attribut existiert noch
"" abc123XYZ true

Inline-Style mit Nonce zur Laufzeit einfügen

// CSP: style-src 'nonce-abc123XYZ'
const nonce = document.querySelector('script[nonce]')?.nonce ?? '';

const style = document.createElement('style');
style.nonce = nonce;
style.textContent = '.banner { background: gold; }';
document.head.append(style);

console.log(style.nonce === nonce);
true

// Wichtig · Fallstricke

  • Neue Nonce pro Antwort: Die Nonce muss für jede HTTP-Antwort neu erzeugt werden, kryptografisch zufällig sein (mindestens 128 Bit, z. B. crypto.randomBytes(16).toString('base64') in Node.js) und darf nie wiederverwendet werden. Vorsicht bei HTML-Caching durch CDN oder Service Worker: Eine zwischengespeicherte Seite liefert immer dieselbe Nonce aus, und der Schutz ist wirkungslos.
  • Kein Ersatz für XSS-Schutz: Jedes Skript, das bereits ausgeführt wird, kann element.nonce lesen. Kann ein Angreifer eigenes JavaScript in ein vertrauenswürdiges Skript einschleusen, etwa über eval oder unsichere JSONP-Endpunkte, kommt er auch an die Nonce. Maskieren Sie Nutzereingaben deshalb weiterhin sauber.
  • Nicht über getAttribute lesen: Wegen des Nonce-Hidings liefert getAttribute('nonce') bei einer Header-CSP einen leeren String. Lesen Sie immer element.nonce.
  • Reihenfolge: Die Nonce muss gesetzt sein, bevor das Element eingefügt wird. Nachträgliches Setzen macht ein bereits blockiertes Skript nicht nachträglich lauffähig.
  • Browser-Kompatibilität: Ältere Browser (z. B. Firefox vor 75, Safari vor 15.4) unterstützen die IDL-Eigenschaft nicht vollständig. Dort hilft als Rückfall el.nonce || el.getAttribute('nonce'). Das Nonce-Hiding gibt es dort unter Umständen ebenfalls nicht.