See how dompurify compares to other vendors in security performance
DOMPurify is a DOM-only cross-site scripting sanitizer for HTML, MathML, and SVG. Prior to 3.4.7, DOMPurify INPLACE sanitization could skip shadow contents attached to an element inside <template>.content, allowing attacker-controlled markup such as event handlers, JavaScript URLs, or scripts to survive and execute when an application cloned and inserted the sanitized template. This issue is fixed in version 3.4.7.
DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. It has been discovered that malicious HTML using special nesting techniques can bypass the depth checking added to DOMPurify in recent releases. It was also possible to use Prototype Pollution to weaken the depth check. This renders dompurify unable to avoid cross site scripting (XSS) attacks. This issue has been addressed in versions 2.5.4 and 3.1.3 of DOMPurify. All users are advised to upgrade. There are no known workarounds for this vulnerability.
DOMPurify 3.0.0 before 3.4.9 does not reset the retained Trusted Types policy when clearConfig() is called, so a DOMPurify instance reused across trust boundaries stays bound to a previously supplied TRUSTEDTYPESPOLICY. A later caller that requests RETURNTRUSTEDTYPE output receives a TrustedHTML object created by the old (potentially unsafe) policy rather than a clean default, which can lead to script execution at a Trusted Types sink. Passing TRUSTEDTYPESPOLICY: null on the later call also does not clear the retained policy.
DOMPurify versions >=3.0.0 and before 3.4.8, when configured with SAFEFORTEMPLATES together with a DOM output mode (RETURNDOM, RETURNDOMFRAGMENT, or INPLACE), fail to strip template expressions (e.g. ${evil}, {{evil}}, <%evil%>) inside <template> element content. The final normalization/scrub pass (scrubTemplateExpressions) uses a NodeIterator and node.normalize() that do not descend into template.content, so expressions that only form after adjacent text nodes merge survive sanitization. This bypasses SAFEFORTEMPLATES and can allow a downstream template engine to evaluate attacker-supplied expressions. The string output path is not affected.
DOMPurify through 3.4.6 contains a cross-site scripting vulnerability in INPLACE mode that trusts attacker-controlled nodeName on live non-form nodes. Attackers can supply hostile live DOM objects with real script children whose observable nodeName is clobbered to appear as allowed elements, causing scripts to execute when the sanitized tree is inserted into a live document.
DOMPurify before 3.4.7 (affected versions <= 3.4.5) passes direct references to the module-level DEFAULTALLOWEDTAGS and DEFAULTALLOWEDATTR sets to the uponSanitizeElement and uponSanitizeAttribute hooks via data.allowedTags / data.allowedAttributes when sanitize is called without an explicit cfg.ALLOWEDTAGS / cfg.ALLOWEDATTR array. A hook that mutates these fields permanently widens the default allow-lists for the lifetime of the DOMPurify instance, so all subsequent default-config sanitize calls inherit the widened defaults and attacker payloads using the poisoned tag/attribute name survive sanitization. removeAllHooks(), clearConfig(), and passing a fresh cfg do not recover the state; only constructing a new DOMPurify instance does.
DOMPurify before 3.4.0 contains a logic error in the ADDTAGS function where short-circuit evaluation allows forbidden tags to bypass FORBIDTAGS restrictions. Attackers can craft input containing tags listed in FORBIDTAGS that are also added via ADDTAGS function, causing them to be retained in sanitized output.
DOMPurify through 3.3.3 fails to sanitize DOM elements passed via INPLACE mode when the element originates from a different window/realm (e.g., an iframe's contentDocument). A cross-realm instanceof check in the private isNode() function returns false for foreign-realm nodes, causing DOMPurify to stringify the element (yielding '[object HTMLDivElement]'), silently reset INPLACE to false, and return the unsanitized element unchanged with any XSS payloads intact.
In DOMPurify through 3.3.3, function predicates supplied via ADDATTR or ADDTAGS to DOMPurify.sanitize() persist in internal state (EXTRAELEMENTHANDLING) across subsequent sanitize() calls on the same instance. If a later call on the same instance provides ADDATTR or ADDTAGS as an array rather than a function, the previously set function handler is neither cleared nor overwritten, so it continues to approve attacker-controlled attributes or tags. This can allow dangerous event-handler attributes or forbidden tags (bypassing FORBIDTAGS) to survive sanitization, resulting in cross-site scripting. The vendor (Cure53) considers this an edge case outside DOMPurify's threat model; the referenced advisory lists 3.4.0 as the patched version.
DOMPurify before 3.3.2 contains a prototype pollution vulnerability in USEPROFILES mode that allows attackers to bypass attribute filtering by polluting Array.prototype properties. Attackers can set Array.prototype properties like onclick to true, causing DOMPurify to accept event handlers as allowlisted attributes and resulting in DOM-based XSS when sanitized markup is rendered.
DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. DOMPurify was vulnerable to prototype pollution. This vulnerability is fixed in 2.4.2.
image-size is vulnerable to a Denial-of-Service vulnerability when processing specially crafted images.
DOMPurify before 3.2.4 has an incorrect template literal regular expression when SAFEFORTEMPLATES is set to true, sometimes leading to mutation cross-site scripting (mXSS).
DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. DOMpurify was vulnerable to nesting-based mXSS. This vulnerability is fixed in 2.5.0 and 3.1.3.