Signatur
Beschreibung
Eine TrustedTypePolicy ist das zentrale Bauteil der Trusted Types API, die DOM-basiertes Cross-Site-Scripting (DOM-XSS) verhindern soll. Die Richtlinie legt fest, wie aus einem beliebigen String ein „vertrauenswürdiger“ Wert entsteht. Der Browser akzeptiert diesen Wert dann in gefährlichen Senken wie Element.innerHTML, eval() oder HTMLScriptElement.src. Ist die CSP-Direktive require-trusted-types-for 'script' aktiv, lösen reine Strings an diesen Stellen einen TypeError aus.
Ein Objekt dieses Typs lässt sich nicht direkt mit new anlegen. Man erzeugt es über trustedTypes.createPolicy(name, policyOptions). Im Optionsobjekt übergibt man die Callbacks createHTML, createScript und createScriptURL. Darin steckt die eigentliche Sicherheitslogik, zum Beispiel ein Sanitizer wie DOMPurify oder eine Allowlist für URLs. Die Richtlinie stellt die gleichnamigen Methoden bereit. Sie rufen den jeweiligen Callback auf und verpacken dessen Ergebnis in TrustedHTML, TrustedScript oder TrustedScriptURL.
Mitglieder des Interfaces:
name(nur lesbar): der Name der Richtlinie, wie er ancreatePolicy()übergeben wurde.createHTML(input, ...args): gibt einTrustedHTMLzurück.createScript(input, ...args): gibt einTrustedScriptzurück.createScriptURL(input, ...args): gibt einTrustedScriptURLzurück.
Die Richtlinie ist nur so sicher wie ihre Callbacks. Deshalb sollte es möglichst wenige Richtlinien geben, und man sollte sie zentral prüfen. Welche Namen erlaubt sind, steuert die CSP-Direktive trusted-types.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $input Pflicht | string | Der unsichere Eingabe-String, den die Methoden createHTML(), createScript() und createScriptURL() an den passenden Callback der Richtlinie weiterreichen. |
|
| $...args | any[] | Beliebige weitere Argumente. Sie werden unverändert an den Callback übergeben, etwa als Kontext für die Bereinigung. |
Rückgabewert
TypeError. Gibt der Callback null oder undefined zurück, enthält das Objekt einen leeren String.Beispiele
Richtlinie anlegen und HTML sicher einfügen
// Voraussetzung: CSP-Header
// Content-Security-Policy: require-trusted-types-for 'script'; trusted-types escape-policy
const escapePolicy = trustedTypes.createPolicy('escape-policy', {
createHTML: (input) => input
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>')
});
const userInput = '<img src=x onerror=alert(1)>';
const safe = escapePolicy.createHTML(userInput);
document.querySelector('#output').innerHTML = safe;
console.log(escapePolicy.name);
console.log(safe instanceof TrustedHTML, safe.toString());
Skript-URLs mit einer Allowlist prüfen
const allowedOrigins = ['https://cdn.example.com'];
const urlPolicy = trustedTypes.createPolicy('script-loader', {
createScriptURL: (input) => {
const url = new URL(input, location.href);
if (!allowedOrigins.includes(url.origin)) {
throw new TypeError(`Nicht erlaubte Skriptquelle: ${url.origin}`);
}
return url.href;
}
});
const script = document.createElement('script');
script.src = urlPolicy.createScriptURL('https://cdn.example.com/lib.js');
document.head.append(script);
try {
urlPolicy.createScriptURL('https://evil.example.org/x.js');
} catch (err) {
console.error(err.message);
}
DOMPurify als Sanitizer mit Feature-Erkennung
import DOMPurify from 'dompurify';
// Fallback für Browser ohne Trusted Types
const sanitizerPolicy = window.trustedTypes?.createPolicy('sanitizer', {
createHTML: (dirty) => DOMPurify.sanitize(dirty)
}) ?? { createHTML: (dirty) => DOMPurify.sanitize(dirty) };
const renderComment = (el, html) => {
el.innerHTML = sanitizerPolicy.createHTML(html);
};
renderComment(document.querySelector('.comment'), '<b>Hallo</b><script>alert(1)<\/script>');
console.log(document.querySelector('.comment').innerHTML);
Fehlender Callback führt zu TypeError
const htmlOnly = trustedTypes.createPolicy('html-only', {
createHTML: (s) => s.trim()
});
try {
htmlOnly.createScript('console.log(1)');
} catch (err) {
console.log(err instanceof TypeError);
}
// Wichtig · Fallstricke
Sicherheit: Eine Richtlinie mit einem Durchreich-Callback wie createHTML: s => s hebelt den gesamten Schutz aus. Die Callbacks müssen tatsächlich bereinigen oder validieren. Verwende dafür am besten eine erprobte Bibliothek wie DOMPurify und keine selbst geschriebenen regulären Ausdrücke.
CSP: Mit trusted-types name1 name2 legst du fest, welche Richtliniennamen erlaubt sind. Standardmäßig darf jeder Name nur einmal vergeben werden. Wer ihn mehrfach nutzen will, braucht 'allow-duplicates'. Für einen nicht erlaubten Namen wirft createPolicy() einen Fehler. Eine Richtlinie mit dem Namen default wird automatisch angewendet, wenn ein String in eine Senke gelangt. Das hilft beim Umstellen, verbirgt aber leicht unsichere Stellen im Code.
Zum Testen: Content-Security-Policy-Report-Only meldet Verstöße nur, statt sie zu blockieren. So findest du alle betroffenen Stellen, bevor du die Durchsetzung aktivierst.
Kompatibilität: Chromium-Browser unterstützen die API seit Version 83. Safari und Firefox sind erst in neueren Versionen hinzugekommen (Safari 26, Firefox 145). Prüfe vor dem Einsatz window.trustedTypes. Für ältere Browser gibt es ein Polyfill (trusted-types von W3C/Google). Ohne Unterstützung akzeptieren die Senken weiterhin normale Strings.