Zurück zu den Updates
New releaseAug 3, 2026

DOMPurify v3.4.13

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:

Teilen

DOMPurify

npm License Downloads dependents npm package minimized gzipped size (select exports) Cloudback

OpenSSF Best Practices Build & Test OpenSSF Scorecard Socket Badge snyk.io package health

DOMPurify ist ein reiner DOM-basierter, superschneller, extrem toleranter XSS-Sanitizer für HTML, MathML und SVG.

Die Nutzung und der Einstieg sind ebenfalls sehr einfach. DOMPurify wurde im Februar 2014 gestartet und hat inzwischen die Version v3.4.14 erreicht.

DOMPurify läuft als JavaScript und funktioniert in allen modernen Browsern (Safari (10+), Opera (15+), Edge, Firefox und Chrome – sowie in nahezu allem anderen, das Blink, Gecko oder WebKit verwendet). Es bricht nicht bei MSIE oder anderen veralteten Browsern. Es tut dort einfach nichts.

Beachten Sie, dass DOMPurify v2.5.9 die neueste 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-/Betriebssystem-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), sodass auch Regressionen in veralteten Browsern erkannt werden. Wir führen DOMPurify außerdem mit Node.js v20, v22, v24, v25 und v26 auf jsdom aus. Ältere Node-Versionen funktionieren bekanntermaßen ebenfalls, aber ... keine Garantien.

DOMPurify wurde von Sicherheitsexperten geschrieben, die über umfangreiche Erfahrung mit Web-Angriffen und XSS verfügen. Keine Sorge. Für weitere Details lesen Sie bitte auch unsere Security Goals & Threat Model. Bitte lesen Sie das. Wirklich. Und wenn Sie die grausigen Details mögen, katalogisiert die Seite Attack Classes & Bypass History die Parser-Mutations-, Namespace-, Clobbering- und Template-Tricks, gegen die DOMPurify verteidigt.

Das DOMPurify-Projekt inspirierte die Erstellung 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?

DOMPurify bereinigt HTML und verhindert XSS-Angriffe. Sie können DOMPurify beispielsweise einen 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 Unannehmlichkeiten. 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 auf Ihrer Website ein.

Verwendung der unminifizierten 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 Zeichenfolgen 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 mithilfe von innerHTML in ein DOM-Element oder mithilfe von document.write() in das DOM geschrieben werden. Das bleibt ganz Ihnen überlassen. Beachten Sie, dass wir standardmäßig HTML, SVG und MathML zulassen. Wenn Sie nur HTML benötigen, was ein sehr häufiger Anwendungsfall sein könnte, können Sie das ebenfalls problemlos einrichten:```js const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });

### Gibt es potenzielle Stolperfallen?

Bitte beachten Sie, dass Sie die Wirkung der Bereinigung leicht **zunichtemachen können**, wenn Sie HTML _zuerst_ bereinigen und es _danach_ verändern. Wenn Sie das bereinigte Markup _nach_ der Bereinigung an eine andere Bibliothek übergeben, stellen Sie sicher, dass diese Bibliothek das HTML nicht eigenständig verändert. Siehe [Security Goals & Threat Model](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model) für sichere Anwendungsrezepte und die Tags/Attribute, die man sich zweimal überlegen sollte, sowie [Attack Classes & Bypass History](https://github.com/cure53/DOMPurify/wiki/Attack-Classes-&-Bypass-History) dafür, warum Nachbearbeitung und Änderung des Markup-Kontexts die Bereinigung aushebeln.

### Okay, das klingt logisch, weiter geht's

Nach der Bereinigung Ihres Markups können Sie auch einen Blick auf die Eigenschaft `DOMPurify.removed` werfen und herausfinden, welche Elemente und Attribute entfernt wurden. Bitte **verwenden Sie diese Eigenschaft nicht** für sicherheitskritische Entscheidungen. Sie ist nur eine kleine Hilfe für Neugierige.

### DOMPurify auf dem Server ausführen

DOMPurify funktioniert technisch auch serverseitig mit Node.js. Unser Support orientiert sich am [Node.js-Release-Zyklus](https://nodejs.org/en/about/previous-releases).

Die Ausführung von DOMPurify auf dem Server erfordert ein vorhandenes DOM – das dürfte keine Überraschung sein. Üblicherweise ist [jsdom](https://github.com/jsdom/jsdom) das Werkzeug der Wahl, und wir **empfehlen dringend**, die neueste Version von _jsdom_ zu verwenden.

Warum? Weil ältere Versionen von _jsdom_ bekanntermaßen auf eine Weise fehlerhaft sind, die zu XSS führt, _selbst wenn_ DOMPurify alles zu 100 % korrekt macht. Es gibt **bekannte Angriffsvektoren**, z. B. in _jsdom v19.0.0_, die in _jsdom v20.0.0_ behoben sind – und genau deshalb empfehlen wir, _jsdom_ aktuell zu halten.

Bitte beachten Sie außerdem, dass es Tools wie [happy-dom](https://github.com/capricorn86/happy-dom) gibt, diese aber derzeit **nicht als sicher gelten**. Die Kombination von DOMPurify mit _happy-dom_ wird derzeit nicht empfohlen und führt wahrscheinlich zu XSS. Für Hintergründe dazu, warum das serverseitige DOM Ihrer Wahl Teil Ihrer vertrauenswürdigen Rechenbasis ist, siehe [Attack Classes & Bypass History](https://github.com/cure53/DOMPurify/wiki/Attack-Classes-&-Bypass-History).

Abgesehen davon können Sie DOMPurify problemlos auf dem Server verwenden. Vermutlich. Das hängt wirklich von _jsdom_ oder dem DOM ab, das Sie serverseitig nutzen. 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 das funktionieren:```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 das hier, wenn du lieber mit Imports arbeitest:```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 du Probleme hast, es in deiner spezifischen Umgebung zum Laufen zu bringen, wirf einen Blick auf das großartige Projekt isomorphic-dompurify, das viele Probleme löst, auf die Leute stoßen könnten.```bash npm install isomorphic-dompurify

🛡️ Sicherheitshinweis

Wichtig: Dieses Tool ist ausschließlich für autorisierte Sicherheitstests und Bildungszwecke gedacht. Die unbefugte Nutzung dieses Tools gegen Systeme, die Ihnen nicht gehören oder für die Sie keine ausdrückliche schriftliche Genehmigung haben, ist illegal und unethisch.

Der Autor und Kitploit übernehmen keinerlei Verantwortung für Missbrauch, Schäden oder rechtliche Konsequenzen, die sich aus der Nutzung dieses Tools ergeben. Sie sind allein für die Einhaltung aller geltenden Gesetze und Vorschriften in Ihrer Gerichtsbarkeit verantwortlich.

Durch die Nutzung dieses Tools erklären Sie sich damit einverstanden, dass:

  • Sie die ausdrückliche Genehmigung des Eigentümers des Zielsystems haben.
  • Sie dieses Tool nur in Übereinstimmung mit allen geltenden Gesetzen verwenden.
  • Sie die volle Verantwortung für alle Handlungen übernehmen, die mit diesem Tool durchgeführt werden.
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](https://cure53.de/purify)

## Was, wenn ich einen Sicherheitsfehler finde?

Zunächst kontaktieren Sie uns bitte umgehend per [E-Mail](mailto:[email protected]), damit wir an einem Fix arbeiten können. [PGP-Schlüssel](https://keyserver.ubuntu.com/pks/lookup?op=vindex&search=0xC26C858090F70ADA)

Außerdem qualifizieren Sie sich wahrscheinlich für ein Bug-Bounty! Die netten Leute bei [Fastmail](https://www.fastmail.com/) verwenden DOMPurify für ihre Dienste und haben unsere Bibliothek in den Umfang ihres Bug-Bounty-Programms 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](https://www.fastmail.com/about/bugbounty/).

## Ein paar Beispiele für die Bereinigung?

Wie sieht bereinigtes Markup aus? Nun, [die Demo](https://cure53.de/purify) zeigt es für eine große Menge bösartiger Elemente. Aber lassen Sie uns auch einige kleinere Beispiele zeigen!```js
DOMPurify.sanitize(''); // becomes <img src="https://raw.githubusercontent.com/cure53/dompurify/main/x">
DOMPurify.sanitize('<svg><g/onload=alert(2)//<p>'); // becomes <svg><g></g></svg>
DOMPurify.sanitize('<p>abcdef</p>'); // becomes <p>abc</p>
DOMPurify.sanitize('<math><mi//xlink:href="data:x,<script>alert(4)</script>">'); // becomes <math><mi></mi></math>
DOMPurify.sanitize('<TABLE><tr><td>HELLO</tr></TABL>'); // becomes <table><tbody><tr><td>HELLO</td></tr></tbody></table>
DOMPurify.sanitize('<UL><li><A HREF=//google.com>click</UL>'); // becomes <ul><li><a href="//google.com">click</a></li></ul>
```
Das sind nur ein kleiner Vorgeschmack. Für die vollständige Taxonomie der Angriffsklassen, aus denen diese Beispiele stammen – Mutation XSS, Namespace-Konfusion, 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-Vorlagen rekursiv. DOMPurify ermöglicht es Ihnen zudem, HTML für die Verwendung mit der jQuery-`$()`- und `elm.html()`-API ohne bekannte Probleme zu bereinigen. 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 veralteten Browsern wie dem Internet Explorer?

DOMPurify tut überhaupt nichts. Es gibt einfach exakt den String zurück, den Sie ihm übergeben haben. DOMPurify stellt eine Eigenschaft namens `isSupported` bereit, die Ihnen mitteilt, ob es seine Aufgabe erfüllen kann, sodass Sie sich einen eigenen Backup-Plan ausdenken können.

## Was ist mit DOMPurify und Trusted Types?

In Version 1.0.9 wurde die 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).

Beachten Sie, dass für die Erstellung einer Policy in `trustedTypes` mit 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 keine `TRUSTED_TYPES_POLICY` angegeben ist, versucht DOMPurify, eine eigene interne Trusted-Types-Richtlinie mit dem Namen `dompurify` zu erstellen. Wenn Ihre Seite bereits eine eigene Richtlinie zusammen mit einer strengen CSP definiert (zum Beispiel `trusted-types my-organization`), die eine Richtlinie mit dem Namen `dompurify` nicht zulässt, wird dieser Versuch vom Browser blockiert und eine Warnung `TrustedTypes policy dompurify could not be created.` zusammen mit einer CSP-Verletzung protokolliert.

Um zu verhindern, dass DOMPurify seine interne Fallback-Richtlinie erstellt, übergeben Sie `TRUSTED_TYPES_POLICY: null`. Dies ist die richtige Wahl, wenn Sie `DOMPurify.sanitize` von innerhalb des `createHTML` Ihrer eigenen Richtlinie aufrufen, und bedeutet, dass Sie `dompurify` nicht zur `trusted-types`-Zulassungsliste 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`-Methode dieser Policy bereits `DOMPurify.sanitize` aufruft. Das ist per Definition zirkulär – das Sanitizing würde die Policy aufrufen, die wiederum durch den erneuten DOMPurify-Aufruf sanitized – und DOMPurify wird einen beschreibenden `TypeError` werfen, um die Endlosrekursion zu verhindern. Deine eigene Policy sollte DOMPurify aufrufen; DOMPurify sollte nicht so konfiguriert sein, dass es deine Policy aufruft.

Wenn du dieses `default`-Policy-Muster automatisch auf eine gesamte Seite anwenden möchtest – sodass jede HTML-Senke sanitized wird, einschließlich Legacy-Code, Widgets von Drittanbietern und der Tausenden von `innerHTML`-Zuweisungen, die du nicht leicht finden oder umschreiben kannst – wirf einen Blick auf [DOMFortify](https://github.com/cure53/DOMFortify). Es installiert genau eine solche Trusted-Types-`default`-Policy, die von DOMPurify unterstützt wird, und lehnt Script-Senken (`eval`, `script.src`, ...) rundweg ab. Es ist bewusst ein separates Projekt: DOMPurify bleibt ein fokussierter Sanitizer, und DOMFortify übernimmt die dokumentweite Durchsetzungsebene, die absichtlich außerhalb des Anwendungsbereichs 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-Liste erweiterst (`ADD_TAGS`, `ADD_ATTR`, `CUSTOM_ELEMENT_HANDLING`, …) oder einen Standardwert 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 });
```
### Steuern Sie unsere Allow-Listen und Block-Listen```js
// allow only <b> elements, very strict
const clean = DOMPurify.sanitize(dirty, { ALLOWED_TAGS: ['b'] });

// allow only <b> and <q> 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 <style> 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 <my-tag> 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(
  '<one attribute-one="1" attribute-two="2"></one><two attribute-one="1" attribute-two="2"></two>',
  {
    ADD_TAGS: (tagName) => {
      return Object.keys(allowlist).includes(tagName);
    },
    ADD_ATTR: (attributeName, tagName) => {
      return allowlist[tagName]?.includes(attributeName) || false;
    },
  }
); // <one attribute-one="1"></one><two attribute-two="2"></two>

// 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 });
```
### Steuerungsverhalten in Bezug auf Custom Elements```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>
```
### Steuerungsverhalten in Bezug auf URI-Werte```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'] });
```
### Steuerung zulässiger Attributwerte```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',
});
```
### Einfluss darauf, wo wir bereinigen```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 [hier noch weitere Beispiele](https://github.com/cure53/DOMPurify/tree/main/demos#what-is-this), die zeigen, wie Sie DOMPurify ausführen, anpassen und konfigurieren können, um es an Ihre Bedürfnisse anzupassen.

## Persistente Konfiguration

Anstatt dieselbe Konfiguration wiederholt an `DOMPurify.sanitize` zu übergeben, können Sie die Methode `DOMPurify.setConfig` verwenden. Ihre Konfiguration bleibt erhalten, bis Sie `DOMPurify.setConfig` erneut aufrufen oder `DOMPurify.clearConfig` aufrufen, um sie zurückzusetzen. Denken Sie 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 Ihnen, seine Funktionalität zu erweitern, indem Sie eine oder mehrere Funktionen mit der Methode `DOMPurify.addHook` an einen der folgenden Hooks anhängen:

- `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 sowie die DOMPurify-Konfiguration an den Callback. Schauen Sie sich die [MentalJS-Hook-Demo](https://github.com/cure53/DOMPurify/blob/main/demos/hooks-mentaljs-demo.html) an, um zu sehen, wie die API gut genutzt 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, auch nicht 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 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 bereinigt. Da der verschachtelte Aufruf typischerweise mit der Standardkonfiguration läuft, kann eine strenge `ALLOWED_TAGS`-Allowlist mitten in einem Dokument stillschweigend wieder auf die Standardkonfiguration erweitert werden – ohne Fehler und ohne Warnung.

Wenn Sie verschachteltes Markup bereinigen müssen, beispielsweise ein HTML-Fragment, das in einem Attributwert enthalten ist, haben Sie zwei sichere Optionen. Entweder setzen Sie Ihre Konfiguration einmalig mit [`DOMPurify.setConfig`](#persistent-configuration), statt sie pro 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 bereinigen 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 sowie ein bei Merge ausgelöster Workflow führt die Testsuite erneut auf älteren Engine-Snapshots aus, sodass auch Brüche in veralteten Browsern erkannt werden. Die Build-Logs finden Sie hier: https://github.com/cure53/DOMPurify/actions

Sie können lokale Tests außerdem durch Ausführen von `npm run test` starten.

Alle relevanten Commits werden zur zusätzlichen Sicherheit mit dem Schlüssel `0x24BB6BF4` 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 einer veralteten Version von `npm` können wir die Versionen der installierten Abhängigkeiten nicht vollständig gewährleisten, was zu unerwarteten Problemen führen kann.

#### Skripte

Wir verwenden ESLint über `xo` als Teil unseres Pre-Commit-Workflows, um die Konsistenz des Codes sicherzustellen. Darüber hinaus verwenden wir [Prettier](https://github.com/prettier/prettier) für die Formatierung von Quellcode und Markdown, und die `/dist`-Assets werden über `rollup` erstellt.

Dies sind unsere npm-Skripte:

- `npm run dev`, um das unminifizierte UMD-Bundle zu erstellen und dabei die Quellen auf Änderungen zu überwachen
- `npm run test`, um die Quellen zu linten, Tests über jsdom auszuführen und Browsertests in Chromium über Playwright auszuführen
  - `npm run test:jsdom`, um nur Tests über jsdom auszuführen
  - `npm run test:happydom`, um die Suite über happy-dom auszuführen (eine nicht unterstützte Umgebung; als Robustheitsprüfung beibehalten, nicht als Kompatibilitätsversprechen)
  - `npm run test:browser`, um nur Tests über Playwright auszuführen
  - `npm run test:browser:legacy`, um die Suite auf älteren Browser-Engines auszuführen (weisen Sie `PW_MODULE` auf eine festgelegte alte Playwright-Installation; siehe `.github/workflows/legacy-browsers.yml`)
  - `npm run test:ci`, um den CI-Testablauf für jsdom und Playwright auszuführen
  - `npm run test:fuzz`, um einen kleinen Fuzzer auszuführen, der `sanitize()` und CONFIG abdeckt
- `npm run bench`, um das jsdom-Mikro-Benchmark über das erstellte `dist/purify.cjs` auszuführen (zuerst erstellen; `--json` und `--compare a.json b.json` unterstützen A/B-Läufe über Branches hinweg – Ergebnisse sind richtungsweisend, bestätigen Sie benutzerbezogene Behauptungen in echten Browsern)
- `npm run coverage`, um ein instrumentiertes Bundle zu erstellen, die jsdom-Suite auszuführen und einen lokalen HTML-Zeilen-/Zweigabdeckungsbericht in `coverage/index.html` zu schreiben (nur jsdom-Bereich, nicht in CI ausgeführt)
  - `npm run build:cov`, um nur das instrumentierte Coverage-Bundle zu erstellen
- `npm run lint`, um die Quellen mit ESLint über xo zu linten
- `npm run format`, um JavaScript/TypeScript- und Markdown-Quellen mit Prettier zu formatieren
  - `npm run format:js`, um nur JavaScript/TypeScript-Quellen zu formatieren
  - `npm run format:md`, um nur Markdown-Dateien zu formatieren
- `npm run build`, um Typdeklarationen und Distributions-Bundles zu erstellen und anschließend generierte Typen zu korrigieren und zu bereinigen
  - `npm run build:types`, um nur TypeScript-Deklarationsdateien zu erstellen
  - `npm run build:rollup`, um alle Rollup-Bundles zu erstellen
  - `npm run build:umd`, um nur ein unminifiziertes UMD-Bundle zu erstellen
  - `npm run build:umd:min`, um nur ein minifiziertes UMD-Bundle zu erstellen
  - `npm run build:es`, um nur das ES-Modul-Bundle zu erstellen
  - `npm run build:cjs`, um nur das CommonJS-Bundle zu erstellen
  - `npm run build:fix-types`, um generierte Typdateien nachzubearbeiten
  - `npm run build:cleanup`, um temporäre generierte Typausgaben zu bereinigen
- `npm run verify-typescript`, um das TypeScript-Verifizierungsskript auszuführen
- `npm run commit-amend-build`, um das Maintainer-Hilfsskript zum Ändern der Build-Ausgabe auszuführen

Hinweis: Alle ausführbaren Skripte werden über `npm run <script>` ausgelöst.

Es gibt weitere npm-Skripte, die jedoch hauptsächlich der CI-Integration dienen oder als „privat“ gedacht sind, beispielsweise um Distributionsdateien bei jedem Commit zu ändern.

## Sicherheits-Mailingliste

Wir pflegen 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 geschieht, wenn ein Bypass gefunden wurde), wird eine E-Mail an diese Liste gesendet. Dies geschieht normalerweise innerhalb von Minuten oder wenigen Stunden, nachdem wir von einem Bypass erfahren haben. Die Liste kann hier abonniert werden:

[https://lists.ruhr-uni-bochum.de/mailman/listinfo/dompurify-security](https://lists.ruhr-uni-bochum.de/mailman/listinfo/dompurify-security)

Feature-Versionen werden nicht auf dieser Liste angekündigt.

## Wer hat beigetragen?

Viele Menschen haben dazu beigetragen, dass DOMPurify das ist, was es heute ist, und sie verdienen Anerkennung!

[offset](https://github.com/offset), [Bankde](https://github.com/Bankde), [lukewarlow](https://github.com/lukewarlow), [DEMON1A](https://github.com/DEMON1A), [fg0x0](https://github.com/fg0x0), [kodareef5](https://github.com/kodareef5), [DavidOliver](https://github.com/DavidOliver), [1Jesper1](https://github.com/1Jesper1), [bencalif](https://github.com/bencalif), [trace37labs](https://github.com/trace37labs), [eddieran](https://github.com/eddieran), [christos-eth](https://github.com/christos-eth), [researchatfluidattacks](https://github.com/researchatfluidattacks), [frevadiscor](https://github.com/frevadiscor), [Rotzbua](https://github.com/Rotzbua), [binhpv](https://github.com/binhpv), [MariusRumpf](https://github.com/MariusRumpf), [prasadrajandran](https://github.com/prasadrajandran), [Cybozu 💛💸](https://github.com/cybozu), [hata6502 💸](https://github.com/hata6502), [openclaw 💸](https://github.com/openclaw), [intra-mart-dh 💸](https://github.com/intra-mart-dh), [nelstrom ❤️](https://github.com/nelstrom), [hash_kitten ❤️](https://twitter.com/hash_kitten), [kevin_mizu ❤️](https://twitter.com/kevin_mizu), [icesfont ❤️](https://github.com/icesfont), [reduckted ❤️](https://github.com/reduckted), [dcramer 💸](https://github.com/dcramer), [JGraph 💸](https://github.com/jgraph), [baekilda 💸](https://github.com/baekilda), [Healthchecks 💸](https://github.com/healthchecks), [Sentry 💸](https://github.com/getsentry), [jarrodldavis 💸](https://github.com/jarrodldavis), [CynegeticIO](https://github.com/CynegeticIO), [ssi02014 ❤️](https://github.com/ssi02014), [GrantGryczan](https://github.com/GrantGryczan), [Lowdefy](https://twitter.com/lowdefy), [granlem](https://twitter.com/MaximeVeit), [oreoshake](https://github.com/oreoshake), [tdeekens ❤️](https://github.com/tdeekens), [peernohell ❤️](https://github.com/peernohell), [is2ei](https://github.com/is2ei), [SoheilKhodayari](https://github.com/SoheilKhodayari), [franktopel](https://github.com/franktopel), [NateScarlet](https://github.com/NateScarlet), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [terjanq](https://twitter.com/terjanq), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb ❤️](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@shafigullin](https://twitter.com/shafigullin), [@mmrupp](https://twitter.com/mmrupp), [@irsdl](https://twitter.com/irsdl),[ShikariSenpai](https://github.com/ShikariSenpai), [ansjdnakjdnajkd](https://github.com/ansjdnakjdnajkd), [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro), [@CmdEngineer\_](https://twitter.com/CmdEngineer_), [@avr4mit](https://twitter.com/avr4mit), [davecardwell](https://github.com/davecardwell), [Develop-KIM](https://github.com/Develop-KIM), [asamuzaK](https://github.com/asamuzaK), [fishjojo1 ❤️](https://github.com/fishjojo1), [Rikuxx0](https://github.com/Rikuxx0), [donmccurdy](https://github.com/donmccurdy), [hhk-png](https://github.com/hhk-png), [elrion018](https://github.com/elrion018), [michalnieruchalski-tiugo](https://github.com/michalnieruchalski-tiugo), [reey](https://github.com/reey), [KanhaKanhaiya](https://github.com/KanhaKanhaiya), [odaysec](https://github.com/odaysec), [Akokonunes](https://github.com/Akokonunes), [alirezarouhbakhsh](https://github.com/alirezarouhbakhsh), [Jaybhade](https://github.com/Jaybhade) und besonders [@securitymb ❤️](https://twitter.com/securitymb) & [@masatokinugawa ❤️](https://twitter.com/masatokinugawa)

Kategorien