
DOMPurify v3.4.15
DOMPurify - ein ausschließlich auf dem DOM basierender, superschneller, ultratoleranter XSS-Sanitizer für HTML, MathML und SVG. DOMPurify arbeitet mit einer sicheren Standardkonfiguration, bietet aber viele Konfigurationsmöglichkeiten und Hooks. Demo:
DOMPurify
DOMPurify ist ein DOM-basierter, superschneller, äußerst toleranter XSS-Sanitizer für HTML, MathML und SVG.
Er ist außerdem sehr einfach zu verwenden und einzurichten. DOMPurify wurde im Februar 2014 gestartet und hat inzwischen Version v3.4.15 erreicht.
DOMPurify läuft als JavaScript und funktioniert in allen modernen Browsern (Safari (10+), Opera (15+), Edge, Firefox und Chrome – sowie nahezu allem anderen, das Blink, Gecko oder WebKit verwendet). Es bricht nicht auf MSIE oder anderen Legacy-Browsern. Es tut einfach nichts.
Beachten Sie, dass DOMPurify v2.5.9 die letzte Version ist, die MSIE unterstützt. Für wichtige Sicherheitsupdates, die mit MSIE kompatibel sind, verwenden Sie bitte den 2.x-Zweig.
Unsere automatisierten Tests decken bei jedem Push 9 Browser-/OS-Kombinationen auf den aktuellen Engines ab (Chromium, Firefox und WebKit unter Ubuntu, macOS und Windows), und eine separate Matrix führt die Testsuite erneut auf älteren Engine-Snapshots aus (zurück bis etwa Chromium 110, Firefox 108 und WebKit 16.4, also rund drei Jahre alt), damit auch Regressionen auf veralteten Browsern erkannt werden. Wir führen außerdem Node.js v20, v22, v24, v25 und v26 mit DOMPurify auf jsdom aus. Ältere Node-Versionen funktionieren bekanntermaßen ebenfalls, aber hey ... keine Garantien.
DOMPurify wird von Sicherheitsexperten geschrieben, die über umfangreiche Erfahrung mit Webangriffen und XSS verfügen. Keine Sorge. Für weitere Details lesen Sie bitte auch unsere Security Goals & Threat Model. Bitte lesen Sie es. Wirklich. Und wenn Sie die blutigen Details mögen, katalogisiert die Seite Attack Classes & Bypass History die Parser-Mutation-, Namespace-, Clobbering- und Template-Tricks, gegen die DOMPurify sich verteidigt.
Das DOMPurify-Projekt inspirierte die Entwicklung der HTML Sanitizer API, die bereits in vielen Browsern ausgeliefert wird. Dieselbe Fähigkeit wird nun direkt in der WHATWG HTML-Spezifikation standardisiert.
Inhaltsverzeichnis
- Was macht es?
- Wie verwende ich es?
- Gibt es eine Demo?
- Was, wenn ich einen Sicherheits-Bug finde?
- Ein paar Bereinigungsbeispiele bitte?
- Was wird unterstützt?
- Was ist mit Legacy-Browsern wie Internet Explorer?
- Was ist mit DOMPurify und Trusted Types?
- Kann ich DOMPurify konfigurieren?
- Persistente Konfiguration
- Hooks
- Entfernte Konfiguration
- Continuous Integration
- Sicherheits-Mailingliste
- Wer hat beigetragen?
Was macht es?
DOMPurify bereinigt HTML und verhindert XSS-Angriffe. Sie können DOMPurify beispielsweise mit einem String voller unsauberem HTML füttern, und es gibt einen String (sofern nicht anders konfiguriert) mit sauberem HTML zurück. DOMPurify entfernt alles, was gefährliches HTML enthält, und verhindert dadurch XSS-Angriffe und andere Übel. Es ist außerdem verdammt schnell. Wir nutzen die Technologien, die der Browser bereitstellt, und verwandeln sie in einen XSS-Filter. Je schneller Ihr Browser, desto schneller ist DOMPurify.
Wie verwende ich es?
Es ist einfach. Binden Sie DOMPurify einfach in Ihre Website ein.
Verwendung der nicht minimierten Version (Source-Map verfügbar)```html
### Verwendung der minifizierten und getesteten Produktionsversion (Source-Map verfügbar)```html
<script type="text/javascript" src="dist/purify.min.js"></script>
Anschließend können Sie Zeichenketten bereinigen, indem Sie den folgenden Code ausführen:```js const clean = DOMPurify.sanitize(dirty);
Oder vielleicht das hier, wenn du gerne mit Angular oder Ähnlichem arbeitest:```js
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize('<b>hello there</b>');
Das resultierende HTML kann mit innerHTML in ein DOM-Element oder mit document.write() in das DOM geschrieben werden. Das liegt ganz bei Ihnen.
Beachten Sie, dass wir standardmäßig HTML, SVG und MathML zulassen. Wenn Sie nur HTML benötigen, was ein sehr häufiger Anwendungsfall sein dürfte, können Sie das ebenfalls einfach einrichten:```js
const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });
### Gibt es irgendwelche Stolperfallen?
Nun, bitte beachten Sie: Wenn Sie HTML _zuerst_ bereinigen und es _danach_ ändern, können Sie leicht **die Wirkung der Bereinigung zunichtemachen**. Wenn Sie das bereinigte Markup _nach_ der Bereinigung an eine andere Bibliothek weitergeben, stellen Sie bitte sicher, dass die Bibliothek nicht selbst am HTML herummanipuliert. Siehe [Security Goals & Threat Model](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model) für Rezepte zur sicheren Verwendung und die Tags/Attribute, bei denen man zweimal nachdenken sollte, sowie [Attack Classes & Bypass History](https://github.com/cure53/DOMPurify/wiki/Attack-Classes-&-Bypass-History) dafür, warum Nachbearbeitung und das Ändern des Markup-Kontexts die Bereinigung aushebeln.
### Okay, ergibt Sinn, machen wir weiter
Nach der Bereinigung Ihres Markups können Sie sich auch die Eigenschaft `DOMPurify.removed` ansehen und herausfinden, welche Elemente und Attribute entfernt wurden. Bitte **verwenden Sie** diese Eigenschaft **nicht** für sicherheitskritische Entscheidungen. Dies ist nur eine kleine Hilfe für neugierige Gemüter.
### DOMPurify auf dem Server ausführen
DOMPurify funktioniert technisch auch serverseitig mit Node.js. Unser Support bemüht sich, dem [Node.js-Release-Zyklus](https://nodejs.org/en/about/previous-releases) zu folgen.
Um DOMPurify auf dem Server auszuführen, muss ein DOM vorhanden sein, was wohl keine Überraschung ist. Normalerweise ist [jsdom](https://github.com/jsdom/jsdom) das Mittel der Wahl, und wir **empfehlen dringend** die Verwendung der neuesten Version von _jsdom_.
Warum? Weil ältere Versionen von _jsdom_ dafür bekannt sind, auf eine Weise fehlerhaft zu sein, die zu XSS führt, _selbst wenn_ DOMPurify alles zu 100 % korrekt macht. Es gibt **bekannte Angriffsvektoren** in z. B. _jsdom v19.0.0_, die in _jsdom v20.0.0_ behoben sind – und wir empfehlen wirklich, _jsdom_ deshalb aktuell zu halten.
Bitte beachten Sie auch, dass Tools wie [happy-dom](https://github.com/capricorn86/happy-dom) existieren, aber derzeit **nicht als sicher gelten**. Die Kombination von DOMPurify mit _happy-dom_ wird derzeit nicht empfohlen und führt wahrscheinlich zu XSS. Hintergrundinformationen dazu, warum das von Ihnen gewählte serverseitige DOM Teil Ihrer vertrauenswürdigen Rechenbasis ist, finden Sie unter [Attack Classes & Bypass History](https://github.com/cure53/DOMPurify/wiki/Attack-Classes-&-Bypass-History).
Abgesehen davon können Sie DOMPurify bedenkenlos auf dem Server verwenden. Wahrscheinlich. Das hängt wirklich von _jsdom_ oder welchem DOM auch immer Sie serverseitig verwenden ab. Wenn Sie damit leben können, funktioniert es so:```bash
npm install dompurify
npm install jsdom
Für jsdom (bitte eine aktuelle Version verwenden) sollte dies ausreichen:```js const createDOMPurify = require('dompurify'); const { JSDOM } = require('jsdom');
const window = new JSDOM('').window; const DOMPurify = createDOMPurify(window); const clean = DOMPurify.sanitize('hello there');
Oder sogar dies, wenn Sie lieber mit Imports arbeiten:```js
import { JSDOM } from 'jsdom';
import DOMPurify from 'dompurify';
const window = new JSDOM('').window;
const purify = DOMPurify(window);
const clean = purify.sanitize('<b>hello there</b>');
Wenn Sie Probleme haben, es in Ihrer spezifischen Umgebung zum Laufen zu bringen, werfen Sie einen Blick auf das großartige isomorphic-dompurify-Projekt, das viele Probleme löst, auf die man stoßen könnte.```bash npm install isomorphic-dompurify
| `--no-color` | Deaktiviert farbige Ausgabe |
| `--no-banner` | Unterdrückt das Banner |
| `--log-level <level>` | Legt den Log-Level fest (z. B. `info`, `debug`) |
| `--log-file <path>` | Schreibt Logs in eine Datei |
| `--proxy <url>` | Legt einen Proxy fest |
| `--timeout <seconds>` | Legt das Timeout fest |
| `--threads <n>` | Legt die Anzahl der Threads fest |
| `--rate-limit <n>` | Legt das Rate-Limit fest |
| `--output <file>` | Schreibt die Ausgabe in eine Datei |
| `--format <type>` | Legt das Ausgabeformat fest (z. B. `json`, `csv`) |
| `--verbose` | Aktiviert ausführliche Ausgabe |
| `--quiet` | Unterdrückt die Ausgabe |
| `--version` | Zeigt die Version an |
| `--help` | Zeigt die Hilfe an |```js
import DOMPurify from 'isomorphic-dompurify';
const clean = DOMPurify.sanitize('<s>hello</s>');
Gibt es eine Demo?
Natürlich gibt es eine Demo! Spielen Sie mit DOMPurify
Was, wenn ich einen Sicherheitsfehler finde?
Zunächst einmal: Bitte kontaktieren Sie uns umgehend per E-Mail, damit wir an einer Lösung arbeiten können. PGP-Schlüssel
Außerdem qualifizieren Sie sich wahrscheinlich für ein Bug-Bounty! Die netten Leute von Fastmail nutzen DOMPurify für ihre Dienste und haben unsere Bibliothek in ihren Bug-Bounty-Umfang aufgenommen. Wenn Sie also einen Weg finden, DOMPurify zu umgehen oder zu schwächen, werfen Sie bitte auch einen Blick auf deren Website und die Bug-Bounty-Informationen.
Ein paar Bereinigungsbeispiele, bitte?
Wie sieht bereinigtes Markup aus? Nun, die Demo zeigt es für eine große Menge bösartiger Elemente. Aber lassen Sie uns auch einige kleinere Beispiele zeigen!```js
DOMPurify.sanitize(''); // becomes
DOMPurify.sanitize('<g/onload=alert(2)//
'); // becomes DOMPurify.sanitize('
abcdef
'); // becomesabc
DOMPurify.sanitize('<mi//xlink:href="data:x,">'); // becomes DOMPurify.sanitize(''); // becomes| HELLO |
| HELLO |
- <A HREF=//google.com>click
Das ist nur ein kleiner Vorgeschmack. Für die vollständige Taxonomie der Angriffsklassen, aus denen diese Beispiele stammen – Mutation XSS, Namespace Confusion, DOM Clobbering, Rawtext Breakouts und mehr – siehe [Attack Classes & Bypass History](https://github.com/cure53/DOMPurify/wiki/Attack-Classes-&-Bypass-History).
## Was wird unterstützt?
DOMPurify unterstützt derzeit HTML5, SVG und MathML. DOMPurify erlaubt standardmäßig CSS und benutzerdefinierte HTML-Datenattribute. DOMPurify unterstützt außerdem das Shadow DOM – und bereinigt DOM-Templates rekursiv. DOMPurify ermöglicht es dir zudem, HTML für die Verwendung mit der jQuery-`$()`- und `elm.html()`-API zu bereinigen, ohne bekannte Probleme. Für die genaue Menge an Elementen und Attributen, die standardmäßig erlaubt sind, siehe die Wiki-Seite [Default TAGs & ATTRIBUTEs allow-list & blocklist](https://github.com/cure53/DOMPurify/wiki/Default-TAGs-ATTRIBUTEs-allow-list-&-blocklist).
## Was ist mit Legacy-Browsern wie Internet Explorer?
DOMPurify macht überhaupt nichts. Es gibt einfach genau den String zurück, den du ihm übergeben hast. DOMPurify stellt eine Eigenschaft namens `isSupported` bereit, die dir mitteilt, ob es seine Aufgabe erfüllen kann, sodass du deinen eigenen Backup-Plan entwickeln kannst.
## Was ist mit DOMPurify und Trusted Types?
In Version 1.0.9 wurde Unterstützung für die [Trusted Types API](https://github.com/w3c/webappsec-trusted-types) ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API)) zu DOMPurify hinzugefügt.
In Version 2.0.0 wurde ein Konfigurations-Flag hinzugefügt, um das Verhalten von DOMPurify in dieser Hinsicht zu steuern.
Wenn `DOMPurify.sanitize` in einer Umgebung verwendet wird, in der die Trusted Types API verfügbar ist und `RETURN_TRUSTED_TYPE` auf `true` gesetzt ist, versucht es, einen `TrustedHTML`-Wert anstelle eines Strings zurückzugeben (das Verhalten für die Konfigurationsoptionen `RETURN_DOM` und `RETURN_DOM_FRAGMENT` ändert sich nicht).
Beachte, dass zum Erstellen einer Policy in `trustedTypes` unter Verwendung von DOMPurify `RETURN_TRUSTED_TYPE: false` erforderlich ist, da `createHTML` einen normalen String erwartet, nicht `TrustedHTML`. Das folgende Beispiel zeigt dies.```js
window.trustedTypes.createPolicy('default', {
createHTML: (to_escape) =>
DOMPurify.sanitize(to_escape, { RETURN_TRUSTED_TYPE: false }),
});
Wenn kein TRUSTED_TYPES_POLICY bereitgestellt wird, versucht DOMPurify, eine eigene interne Trusted Types-Richtlinie namens dompurify zu erstellen. Wenn Ihre Seite bereits eine eigene Richtlinie zusammen mit einer strikten CSP definiert (zum Beispiel trusted-types my-organization), die keine Richtlinie namens dompurify zulässt, wird dieser Versuch vom Browser blockiert und protokolliert eine TrustedTypes policy dompurify could not be created.-Warnung zusammen mit einer CSP-Verletzung.
Um DOMPurify daran zu hindern, seine interne Fallback-Richtlinie zu erstellen, übergeben Sie TRUSTED_TYPES_POLICY: null. Dies ist die richtige Wahl, wenn Sie DOMPurify.sanitize aus dem createHTML Ihrer eigenen Richtlinie heraus aufrufen, und es bedeutet, dass Sie dompurify nicht zur trusted-types-Allowlist Ihrer CSP hinzufügen müssen.```js
window.trustedTypes.createPolicy('my-organization', {
createHTML: (input) =>
DOMPurify.sanitize(input, { TRUSTED_TYPES_POLICY: null }),
});
Gib **nicht** deine eigene Wrapping-Policy als `TRUSTED_TYPES_POLICY` an DOMPurify zurück (zum Beispiel über `DOMPurify.setConfig({ TRUSTED_TYPES_POLICY: myPolicy })`), wenn die `createHTML` dieser Policy bereits `DOMPurify.sanitize` aufruft. Das ist per Definition zirkulär - das Sanitizing würde die Policy aufrufen, die wiederum durch den Aufruf von DOMPurify sanitisiert - und DOMPurify wird einen aussagekräftigen `TypeError` werfen, um die unendliche Rekursion zu verhindern. Deine eigene Policy sollte DOMPurify aufrufen; DOMPurify sollte nicht so konfiguriert werden, dass es deine Policy aufruft.
Wenn du dieses `default`-Policy-Muster automatisch auf eine gesamte Seite anwenden möchtest - sodass jede HTML-Senke sanitisiert wird, einschließlich Legacy-Code, Drittanbieter-Widgets und der Tausenden von `innerHTML`-Zuweisungen, die du nicht leicht finden oder umschreiben kannst - dann wirf einen Blick auf [DOMFortify](https://github.com/cure53/DOMFortify). Es installiert genau eine solche Trusted-Types-`default`-Policy, die auf DOMPurify basiert, und lehnt Script-Senken (`eval`, `script.src`, ...) kategorisch ab. Es ist bewusst ein separates Projekt: DOMPurify bleibt ein fokussierter Sanitizer, und DOMFortify übernimmt die dokumentweite Durchsetzungsschicht, die absichtlich außerhalb des Zuständigkeitsbereichs von DOMPurify liegt.
## Kann ich DOMPurify konfigurieren?
Ja. Die enthaltenen Standardkonfigurationswerte sind bereits ziemlich gut - aber du kannst sie natürlich überschreiben. Schau dir den Ordner [`/demos`](https://github.com/cure53/DOMPurify/tree/main/demos) an, um eine Reihe von Beispielen zu sehen, wie du [DOMPurify anpassen](https://github.com/cure53/DOMPurify/tree/main/demos#what-is-this) kannst.
Bevor du die Allow-List erweiterst (`ADD_TAGS`, `ADD_ATTR`, `CUSTOM_ELEMENT_HANDLING`, …) oder eine Standardeinstellung lockerst, lohnt es sich, die [Tags und Attribute, bei denen man zweimal nachdenken sollte](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model#dangerous-tags-and-attributes-think-twice-before-allow-listing) zu überfliegen - einige sind auf nicht offensichtliche Weise gefährlich.
### Allgemeine Einstellungen```js
// strip {{ ... }}, ${ ... } and <% ... %> to make output safe for template systems
// be careful please, this mode is not recommended for production usage.
// allowing template parsing in user-controlled HTML is not advised at all.
// only use this mode if there is really no alternative.
const clean = DOMPurify.sanitize(dirty, { SAFE_FOR_TEMPLATES: true });
// change how e.g. comments containing risky HTML characters are treated.
// be very careful, this setting should only be set to `false` if you really only handle
// HTML and nothing else, no SVG, MathML or the like.
// Otherwise, changing from `true` to `false` will lead to XSS in this or some other way.
const clean = DOMPurify.sanitize(dirty, { SAFE_FOR_XML: false });
Steuerung unserer Allow-Listen und Block-Listen```js
// allow only elements, very strict const clean = DOMPurify.sanitize(dirty, { ALLOWED_TAGS: ['b'] });
// allow only and with style attributes
const clean = DOMPurify.sanitize(dirty, {
ALLOWED_TAGS: ['b', 'q'],
ALLOWED_ATTR: ['style'],
});
// allow all safe HTML elements but neither SVG nor MathML // note that the USE_PROFILES setting will override the ALLOWED_TAGS setting // so don't use them together const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });
// allow all safe SVG elements and SVG Filters, no HTML or MathML const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { svg: true, svgFilters: true }, });
// allow all safe MathML elements and SVG, but no SVG Filters const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { mathMl: true, svg: true }, });
// change the default namespace from HTML to something different const clean = DOMPurify.sanitize(dirty, { NAMESPACE: 'http://www.w3.org/2000/svg', });
// leave all safe HTML as it is and add elements to block-list const clean = DOMPurify.sanitize(dirty, { FORBID_TAGS: ['style'] });
// leave all safe HTML as it is and add style attributes to block-list const clean = DOMPurify.sanitize(dirty, { FORBID_ATTR: ['style'] });
// extend the existing array of allowed tags and add to allow-list const clean = DOMPurify.sanitize(dirty, { ADD_TAGS: ['my-tag'] });
// extend the existing array of allowed attributes and add my-attr to allow-list const clean = DOMPurify.sanitize(dirty, { ADD_ATTR: ['my-attr'] });
// use functions to control which additional tags and attributes are allowed const allowlist = { one: ['attribute-one'], two: ['attribute-two'], }; const clean = DOMPurify.sanitize( '', { ADD_TAGS: (tagName) => { return Object.keys(allowlist).includes(tagName); }, ADD_ATTR: (attributeName, tagName) => { return allowlist[tagName]?.includes(attributeName) || false; }, } ); //
// prohibit ARIA attributes, leave other safe HTML as is (default is true) const clean = DOMPurify.sanitize(dirty, { ALLOW_ARIA_ATTR: false });
// prohibit HTML5 data attributes, leave other safe HTML as is (default is true) const clean = DOMPurify.sanitize(dirty, { ALLOW_DATA_ATTR: false });
### Verhalten bei benutzerdefinierten Elementen steuern```js
// DOMPurify allows to define rules for Custom Elements. When using the CUSTOM_ELEMENT_HANDLING
// literal, it is possible to define exactly what elements you wish to allow (by default, none are allowed).
//
// The same goes for their attributes. By default, the built-in or configured allow.list is used.
//
// You can use a RegExp literal to specify what is allowed or a predicate, examples for both can be seen below.
// When using a predicate function for attributeNameCheck, it can optionally receive the tagName as a second parameter
// for more granular control over which attributes are allowed for specific elements.
// The default values are very restrictive to prevent accidental XSS bypasses. Handle with great care!
const clean = DOMPurify.sanitize(
'<foo-bar baz="foobar" forbidden="true"></foo-bar><div is="foo-baz"></div>',
{
CUSTOM_ELEMENT_HANDLING: {
tagNameCheck: null, // no custom elements are allowed
attributeNameCheck: null, // default / standard attribute allow-list is used
allowCustomizedBuiltInElements: false, // no customized built-ins allowed
},
}
); // <div is=""></div>
const clean = DOMPurify.sanitize(
'<foo-bar baz="foobar" forbidden="true"></foo-bar><div is="foo-baz"></div>',
{
CUSTOM_ELEMENT_HANDLING: {
tagNameCheck: /^foo-/, // allow all tags starting with "foo-"
attributeNameCheck: /baz/, // allow all attributes containing "baz"
allowCustomizedBuiltInElements: true, // customized built-ins are allowed
},
}
); // <foo-bar baz="foobar"></foo-bar><div is="foo-baz"></div>
const clean = DOMPurify.sanitize(
'<foo-bar baz="foobar" forbidden="true"></foo-bar><div is="foo-baz"></div>',
{
CUSTOM_ELEMENT_HANDLING: {
tagNameCheck: (tagName) => tagName.match(/^foo-/), // allow all tags starting with "foo-"
attributeNameCheck: (attr) => attr.match(/baz/), // allow all containing "baz"
allowCustomizedBuiltInElements: true, // allow customized built-ins
},
}
); // <foo-bar baz="foobar"></foo-bar><div is="foo-baz"></div>
// Example with attributeNameCheck receiving tagName as a second parameter
const clean = DOMPurify.sanitize(
'<element-one attribute-one="1" attribute-two="2"></element-one><element-two attribute-one="1" attribute-two="2"></element-two>',
{
CUSTOM_ELEMENT_HANDLING: {
tagNameCheck: (tagName) => tagName.match(/^element-(one|two)$/),
attributeNameCheck: (attr, tagName) => {
if (tagName === 'element-one') {
return ['attribute-one'].includes(attr);
} else if (tagName === 'element-two') {
return ['attribute-two'].includes(attr);
} else {
return false;
}
},
allowCustomizedBuiltInElements: false,
},
}
); // <element-one attribute-one="1"></element-one><element-two attribute-two="2"></element-two>
Verhalten bei URI-Werten steuern```js
// extend the existing array of elements that can use Data URIs const clean = DOMPurify.sanitize(dirty, { ADD_DATA_URI_TAGS: ['a', 'area'] });
// extend the existing array of elements that are safe for URI-like values (be careful, XSS risk) const clean = DOMPurify.sanitize(dirty, { ADD_URI_SAFE_ATTR: ['my-attr'] });
### Zulässige Attributwerte kontrollieren```js
// allow external protocol handlers in URL attributes (default is false, be careful, XSS risk)
// by default only http, https, ftp, ftps, tel, mailto, callto, sms, cid, xmpp and matrix are allowed.
const clean = DOMPurify.sanitize(dirty, { ALLOW_UNKNOWN_PROTOCOLS: true });
// allow specific protocol handlers in URL attributes via regex (default is false, be careful, XSS risk)
// by default only (protocol-)relative URLs, http, https, ftp, ftps, tel, mailto, callto, sms, cid, xmpp and matrix are allowed.
// Default RegExp: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i;
const clean = DOMPurify.sanitize(dirty, {
ALLOWED_URI_REGEXP:
/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,
});
Den Rückgabetyp beeinflussen```js
// return a DOM HTMLBodyElement instead of an HTML string (default is false) const clean = DOMPurify.sanitize(dirty, { RETURN_DOM: true });
// return a DOM DocumentFragment instead of an HTML string (default is false) const clean = DOMPurify.sanitize(dirty, { RETURN_DOM_FRAGMENT: true });
// use the RETURN_TRUSTED_TYPE flag to turn on Trusted Types support if available const clean = DOMPurify.sanitize(dirty, { RETURN_TRUSTED_TYPE: true }); // will return a TrustedHTML object instead of a string if possible
// use a provided Trusted Types policy const clean = DOMPurify.sanitize(dirty, { // supplied policy must define createHTML and createScriptURL TRUSTED_TYPES_POLICY: trustedTypes.createPolicy('dompurify', { createHTML(s) { return s; }, createScriptURL(s) { return s; }, }), });
// opt out of DOMPurify's internal dompurify Trusted Types policy entirely
// (useful when your CSP trusted-types allowlist does not include dompurify)
const clean = DOMPurify.sanitize(dirty, { TRUSTED_TYPES_POLICY: null });
### Beeinflussen, wie wir bereinigen```js
// return entire document including <html> tags (default is false)
const clean = DOMPurify.sanitize(dirty, { WHOLE_DOCUMENT: true });
// disable DOM Clobbering protection on output (default is true, handle with care, minor XSS risks here)
const clean = DOMPurify.sanitize(dirty, { SANITIZE_DOM: false });
// enforce strict DOM Clobbering protection via namespace isolation (default is false)
// when enabled, isolates the namespace of named properties (i.e., `id` and `name` attributes)
// from JS variables by prefixing them with the string `user-content-`
const clean = DOMPurify.sanitize(dirty, { SANITIZE_NAMED_PROPS: true });
// keep an element's content when the element is removed (default is true)
const clean = DOMPurify.sanitize(dirty, { KEEP_CONTENT: false });
// glue elements like style, script or others to document.body and prevent unintuitive browser behavior in several edge-cases (default is false)
const clean = DOMPurify.sanitize(dirty, { FORCE_BODY: true });
// remove all <a> elements under <p> elements that are removed
const clean = DOMPurify.sanitize(dirty, {
FORBID_CONTENTS: ['a'],
FORBID_TAGS: ['p'],
});
// extend the default FORBID_CONTENTS list to also remove <a> elements under <p> elements
const clean = DOMPurify.sanitize(dirty, {
ADD_FORBID_CONTENTS: ['a'],
FORBID_TAGS: ['p'],
});
// change the parser type so sanitized data is treated as XML and not as HTML, which is the default
const clean = DOMPurify.sanitize(dirty, {
PARSER_MEDIA_TYPE: 'application/xhtml+xml',
});
Einflussbereich der Bereinigung```js
// use the IN_PLACE mode to sanitize a node "in place", which is much faster depending on how you use DOMPurify const dirty = document.createElement('a'); dirty.setAttribute('href', 'javascript:alert(1)');
const clean = DOMPurify.sanitize(dirty, { IN_PLACE: true }); // see https://github.com/cure53/DOMPurify/issues/288 for more info
Es gibt sogar [weitere Beispiele hier](https://github.com/cure53/DOMPurify/tree/main/demos#what-is-this), die zeigen, wie du DOMPurify ausführen, anpassen und konfigurieren kannst, um es an deine Bedürfnisse anzupassen.
## Persistente Konfiguration
Anstatt wiederholt dieselbe Konfiguration an `DOMPurify.sanitize` zu übergeben, kannst du die Methode `DOMPurify.setConfig` verwenden. Deine Konfiguration bleibt bestehen, bis zu deinem nächsten Aufruf von `DOMPurify.setConfig` oder bis du `DOMPurify.clearConfig` aufrufst, um sie zurückzusetzen. Denke daran, dass es nur eine aktive Konfiguration gibt, was bedeutet, dass sobald sie gesetzt ist, alle zusätzlichen Konfigurationsparameter, die an `DOMPurify.sanitize` übergeben werden, ignoriert werden.
## Hooks
DOMPurify ermöglicht es dir, seine Funktionalität zu erweitern, indem du eine oder mehrere Funktionen mit der Methode `DOMPurify.addHook` an einen der folgenden Hooks anhängst:
- `beforeSanitizeElements`
- `uponSanitizeElement` (Kein 's' - wird für jedes Element aufgerufen)
- `afterSanitizeElements`
- `beforeSanitizeAttributes`
- `uponSanitizeAttribute`
- `afterSanitizeAttributes`
- `beforeSanitizeShadowDOM`
- `uponSanitizeShadowNode`
- `afterSanitizeShadowDOM`
Es übergibt den aktuell verarbeiteten DOM-Knoten, bei Bedarf ein Literal mit verifizierten Knoten- und Attributdaten und die DOMPurify-Konfiguration an den Callback. Schau dir die [MentalJS-Hook-Demo](https://github.com/cure53/DOMPurify/blob/main/demos/hooks-mentaljs-demo.html) an, um zu sehen, wie die API schön verwendet werden kann.
_Beispiel_:```js
DOMPurify.addHook(
'uponSanitizeAttribute',
function (currentNode, hookEvent, config) {
// Do something with the current node
// You can also mutate hookEvent for current node (i.e. set hookEvent.forceKeepAttr = true)
// For other than 'uponSanitizeAttribute' hook types hookEvent equals to null
}
);
Ein Hinweis zum Aufruf von sanitize() aus einem Hook
DOMPurify.sanitize() ist nicht re-entrant. Bitte rufen Sie es nicht aus einem Hook heraus auf, oder aus einem Konfigurations-Callback wie CUSTOM_ELEMENT_HANDLING.tagNameCheck oder attributeNameCheck. Diese Callbacks laufen in der Mitte eines aktiven Sanitizer-Durchlaufs.
Ein verschachtelter sanitize()-Aufruf liest die ihm übergebene Konfiguration erneut ein und ersetzt dabei die Konfiguration, die der äußere Durchlauf noch verwendet. Der Rest des äußeren Dokuments wird dann gegen die Konfiguration des verschachtelten Aufrufs statt gegen Ihre eigene sanitisiert. Da der verschachtelte Aufruf typischerweise mit der Standardkonfiguration läuft, kann sich eine strikte ALLOWED_TAGS-Allow-List mitten im Dokument stillschweigend wieder auf die Standardliste erweitern, ohne Fehler und ohne Warnung.
Wenn Sie verschachteltes Markup sanitisieren müssen, zum Beispiel ein HTML-Fragment, das in einem Attributwert enthalten ist, haben Sie zwei sichere Optionen. Entweder legen Sie Ihre Konfiguration einmalig mit DOMPurify.setConfig fest, anstatt sie bei jedem Aufruf zu übergeben, da eine persistente Konfiguration vom verschachtelten Aufruf geteilt wird und für den gesamten Durchlauf in Kraft bleibt; oder Sie sammeln die Fragmente während des Hooks und sanitisieren sie mit einem separaten sanitize()-Aufruf nachdem der äußere zurückgekehrt ist.
Entfernte Konfiguration
| Option | Seit | Hinweis |
|---|---|---|
| SAFE_FOR_JQUERY | 2.1.0 | Kein Ersatz erforderlich. |
Kontinuierliche Integration
Wir verwenden derzeit GitHub Actions in Kombination mit Playwright. Dadurch können wir bei jedem Commit bestätigen, dass alles in den relevanten modernen Browsern funktioniert, und ein separater geplanter und bei Merge ausgelöster Workflow führt die Testsuite erneut auf älteren Engine-Snapshots aus, sodass auch Fehler in veralteten Browsern erkannt werden. Die Build-Logs finden Sie hier: https://github.com/cure53/DOMPurify/actions
Sie können außerdem lokale Tests ausführen, indem Sie npm run test ausführen.
Alle relevanten Commits werden mit dem Schlüssel 0x24BB6BF4 für zusätzliche Sicherheit signiert (seit dem 8. April 2016).
Entwicklung und Mitwirken
Installation (npm i)
Wir unterstützen npm offiziell. Der GitHub Actions Workflow ist so konfiguriert, dass Abhängigkeiten mit npm installiert werden. Bei Verwendung einer veralteten Version von npm können wir die Versionen der installierten Abhängigkeiten nicht vollständig garantieren, was zu unerwarteten Problemen führen kann.
Skripte
Wir verwenden ESLint über xo als Teil unseres Pre-Commit-Workflows, um die Code-Konsistenz zu gewährleisten. Darüber hinaus verwenden wir Prettier für die Formatierung von Quellcode und Markdown, und /dist-Assets werden über rollup erstellt.
Dies sind unsere npm-Skripte:
npm run dev, um das nicht-minifizierte UMD-Bundle zu erstellen und dabei die Quellen auf Änderungen zu überwachennpm run test, um die Quellen zu linten, Tests über jsdom auszuführen und Browsertests in Chromium über Playwright auszuführennpm run test:jsdom, um nur Tests über jsdom auszuführennpm run test:happydom, um die Suite über happy-dom auszuführen (eine nicht unterstützte Umgebung; als Robustheitsprüfung beibehalten, kein Kompatibilitätsversprechen)npm run test:browser, um nur Tests über Playwright auszuführennpm run test:browser:legacy, um die Suite auf älteren Browser-Engines auszuführen (richten SiePW_MODULEauf eine festgeschriebene alte Playwright-Installation; siehe.github/workflows/legacy-browsers.yml)npm run test:ci, um den CI-Testablauf für jsdom und Playwright auszuführennpm run test:fuzz, um einen kleinen Fuzzer auszuführen, dersanitize()und CONFIG abdeckt
npm run bench, um den jsdom-Mikro-Benchmark über das gebautedist/purify.cjsauszuführen (zuerst bauen;--jsonund--compare a.json b.jsonunterstützen A/B-Läufe über Branches hinweg - Ergebnisse sind richtungsweisend, bestätigen Sie benutzerrelevante Aussagen in echten Browsern)npm run coverage, um ein instrumentiertes Bundle zu bauen, die jsdom-Suite auszuführen und einen lokalen HTML-Zeilen-/Branch-Coverage-Bericht nachcoverage/index.htmlzu schreiben (nur jsdom-Umfang, nicht in CI ausgeführt)npm run build:cov, um nur das instrumentierte Coverage-Bundle zu bauen
npm run lint, um die Quellen mit ESLint über xo zu lintennpm run format, um JavaScript/TypeScript- und Markdown-Quellen mit Prettier zu formatierennpm run format:js, um nur JavaScript/TypeScript-Quellen zu formatierennpm run format:md, um nur Markdown-Dateien zu formatieren
npm run build, um Typdeklarationen und Distributions-Bundles zu bauen und dann generierte Typen zu korrigieren und aufzuräumennpm run build:types, um nur TypeScript-Deklarationsdateien auszugebennpm run build:rollup, um alle Rollup-Bundles zu bauennpm run build:umd, um nur ein nicht-minifiziertes UMD-Bundle zu bauennpm run build:umd:min, um nur ein minifiziertes UMD-Bundle zu bauennpm run build:es, um nur das ES-Modul-Bundle zu bauennpm run build:cjs, um nur das CommonJS-Bundle zu bauennpm run build:fix-types, um generierte Typdateien nachzubearbeitennpm run build:cleanup, um temporäre generierte Typausgaben aufzuräumen
npm run verify-typescript, um das TypeScript-Verifikationsskript auszuführennpm run commit-amend-build, um das Maintainer-Hilfsskript zum Ändern der Build-Ausgabe auszuführen
Hinweis: Alle Ausführungsskripte werden über npm run <script> ausgelöst.
Es gibt weitere npm-Skripte, aber sie dienen hauptsächlich der Integration mit CI oder sind als "privat" gedacht, beispielsweise um Build-Distributionsdateien bei jedem Commit zu ändern.
Sicherheits-Mailingliste
Wir unterhalten eine Mailingliste, die benachrichtigt, wann immer eine sicherheitskritische Version von DOMPurify veröffentlicht wurde. Das bedeutet, wenn jemand einen Bypass gefunden hat und wir ihn mit einer Version behoben haben (was immer passiert, wenn ein Bypass gefunden wurde), geht eine E-Mail an diese Liste. Dies geschieht normalerweise innerhalb von Minuten oder einigen Stunden, nachdem wir von einem Bypass erfahren haben. Die Liste kann hier abonniert werden:
https://lists.ruhr-uni-bochum.de/mailman/listinfo/dompurify-security
Feature-Releases werden nicht an diese Liste angekündigt.
Wer hat beigetragen?
Viele Menschen haben dazu beigetragen, dass DOMPurify das geworden ist, was es heute ist, und sie verdienen Anerkennung!
gnyselcuk, leechristensen,offset, Bankde, lukewarlow, DEMON1A, fg0x0, kodareef5, DavidOliver, 1Jesper1, bencalif, trace37labs, eddieran, christos-eth, researchatfluidattacks, frevadiscor, Rotzbua, binhpv, MariusRumpf, prasadrajandran, Cybozu 💛💸, hata6502 💸, openclaw 💸, intra-mart-dh 💸, nelstrom ❤️, hash_kitten ❤️, kevin_mizu ❤️, icesfont ❤️, reduckted ❤️, dcramer 💸, JGraph 💸, baekilda 💸, Healthchecks 💸, Sentry 💸, jarrodldavis 💸, CynegeticIO, ssi02014 ❤️, GrantGryczan, Lowdefy, granlem, oreoshake, tdeekens ❤️, peernohell ❤️, is2ei, SoheilKhodayari, franktopel, NateScarlet, neilj, fhemberger, Joris-van-der-Wel, ydaniv, terjanq, filedescriptor, ConradIrwin, gibson042, choumx, 0xSobky, styfle, koto, tlau88, strugee, oparoz, mathiasbynens, edg2s, dnkolegov, dhardtke, wirehead, thorn0, styu, mozfreddyb ❤️, mikesamuel, jorangreef, jimmyhchan, jameydeorio, jameskraus, hyderali, hansottowirtz, hackvertor, freddyb, flavorjones, djfarrelly, devd, camerondunford, buu700, buildog, alabiaga, Vector919, Robbert, GreLI, FuzzySockets, ArtemBernatskyy, @garethheyes, @shafigullin, @mmrupp, @irsdl,ShikariSenpai, ansjdnakjdnajkd, @asutherland, @mathias, @cgvwzq, @robbertatwork, @giutro, @CmdEngineer_, @avr4mit, davecardwell, Develop-KIM, asamuzaK, fishjojo1 ❤️, Rikuxx0, donmccurdy, hhk-png, elrion018, michalnieruchalski-tiugo, reey, KanhaKanhaiya, odaysec, Akokonunes, alirezarouhbakhsh, Jaybhade und insbesondere @securitymb ❤️ & @masatokinugawa ❤️