chore(deps): update dependency dompurify [security]#13617
Open
renovate[bot] wants to merge 1 commit intomasterfrom
Open
chore(deps): update dependency dompurify [security]#13617renovate[bot] wants to merge 1 commit intomasterfrom
renovate[bot] wants to merge 1 commit intomasterfrom
Conversation
|
Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a changelog item based on your changes. |
|
7fd154d to
8d1031e
Compare
0ab0cf7 to
6b0833b
Compare
80306b3 to
1567ac7
Compare
1567ac7 to
f6c1f86
Compare
f6c1f86 to
f4f9bc2
Compare
f4f9bc2 to
f1f16c1
Compare
f1f16c1 to
6d0b3bb
Compare
6d0b3bb to
f6a0cc0
Compare
f6a0cc0 to
7071327
Compare
7071327 to
5573a63
Compare
6a860e0 to
3dcde18
Compare
3dcde18 to
0b3ac9a
Compare
0b3ac9a to
41eee08
Compare
41eee08 to
749ad8d
Compare
749ad8d to
0e654b3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



This PR contains the following updates:
3.3.1→3.4.0^3.3.1→^3.4.1DOMPurify contains a Cross-site Scripting vulnerability
CVE-2026-0540 / GHSA-v2wj-7wpq-c8vv
More information
Details
DOMPurify 3.1.3 through 3.3.1 and 2.5.3 through 2.5.8, fixed in 2.5.9 and 3.3.2, contain a cross-site scripting vulnerability that allows attackers to bypass attribute sanitization by exploiting five missing rawtext elements (noscript, xmp, noembed, noframes, iframe) in the
SAFE_FOR_XMLregex. Attackers can include payloads like</noscript><img src=x onerror=alert(1)>in attribute values to execute JavaScript when sanitized output is placed inside these unprotected rawtext contexts.Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
DOMPurify is vulnerable to mutation-XSS via Re-Contextualization
GHSA-h8r8-wccr-v5f2
More information
Details
Description
A mutation-XSS (mXSS) condition was confirmed when sanitized HTML is reinserted into a new parsing context using
innerHTMLand special wrappers. The vulnerable wrappers confirmed in browser behavior arescript,xmp,iframe,noembed,noframes, andnoscript. The payload remains seemingly benign afterDOMPurify.sanitize(), but mutates during the second parse into executable markup with an event handler, enabling JavaScript execution in the client (alert(1)in the PoC).Vulnerability
The root cause is context switching after sanitization: sanitized output is treated as trusted and concatenated into a wrapper string (for example,
<xmp> ... </xmp>or other special wrappers) before being reparsed by the browser. In this flow, attacker-controlled text inside an attribute (for example</xmp>or equivalent closing sequences for each wrapper) closes the special parsing context early and reintroduces attacker markup (<img ... onerror=...>) outside the original attribute context. DOMPurify sanitizes the original parse tree, but the application performs a second parse in a different context, reactivating dangerous tokens (classic mXSS pattern).PoC
http://localhost:3001.Wrapper en sinktoxmp.Sanitize + Render.Sanitized responsestill contains the</xmp>sequence insidealt.<img src="x" onerror="alert('expoc')">.alert('expoc')is triggered.{ "name": "expoc", "version": "1.0.0", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node server.js", "dev": "node server.js" }, "keywords": [], "author": "", "license": "ISC", "description": "", "dependencies": { "dompurify": "^3.3.1", "express": "^5.2.1", "jsdom": "^28.1.0" } }Evidence
daft-video.webm
Why This Happens
This is a mutation-XSS pattern caused by a parse-context mismatch:
xmpraw-text behavior).</xmp>) gains structural meaning in parse 2 and alters DOM structure.Sanitization is not a universal guarantee across all future parsing contexts. The sink design reintroduces risk.
Remediation Guidance
innerHTML.textContent,createElement,setAttribute) over string-based HTML composition.xmp,script, etc.).</xmp>,</noscript>, similar parser-breakout markers).Reported by Oscar Uribe, Security Researcher at Fluid Attacks. Camilo Vera and Cristian Vargas from the Fluid Attacks Research Team have identified a mXSS via Re-Contextualization in DomPurify 3.3.1.
Following Fluid Attacks Disclosure Policy, if this report corresponds to a vulnerability and the conditions outlined in the policy are met, this advisory will be published on the website over the next few days (the timeline may vary depending on maintainers' willingness to attend to and respond to this report) at the following URL: https://fluidattacks.com/advisories/daft
Acknowledgements: Camilo Vera and Cristian Vargas.
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
DOMPurify USE_PROFILES prototype pollution allows event handlers
GHSA-cj63-jhhr-wcxv
More information
Details
Summary
When
USE_PROFILESis enabled, DOMPurify rebuildsALLOWED_ATTRas a plain array before populating it with the requested allowlists. Because the sanitizer still looks up attributes viaALLOWED_ATTR[lcName], anyArray.prototypeproperty that is polluted also counts as an allowlisted attribute. An attacker who can setArray.prototype.onclick = true(or a runtime already subject to prototype pollution) can thus force DOMPurify to keep event handlers such asonclickeven when they are normally forbidden. The provided PoC sanitizes<img onclick=...>withUSE_PROFILESand adds the sanitized output to the DOM; the polluted prototype allows the event handler to survive and execute, turning what should be a blocklist into a silent XSS vector.Impact
Prototype pollution makes DOMPurify accept dangerous event handler attributes, which bypasses the sanitizer and results in DOM-based XSS once the sanitized markup is rendered.
Credits
Identified by Cantina’s Apex (https://www.cantina.security).
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:L/VA:N/SC:L/SI:L/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
DOMPurify ADD_ATTR predicate skips URI validation
GHSA-cjmm-f4jc-qw8r
More information
Details
Summary
DOMPurify allows
ADD_ATTRto be provided as a predicate function viaEXTRA_ELEMENT_HANDLING.attributeCheck. When the predicate returnstrue,_isValidAttributeshort-circuits the attribute check before URI-safe validation runs. An attacker who supplies a predicate that accepts specific attribute/tag combinations can then sanitize input such as<a href="javascript:alert(document.domain)">and have thejavascript:URL survive, because URI validation is skipped for that attribute while other checks still pass. The provided PoC acceptshreffor anchors and then triggers a click inside an iframe, showing that the sanitized payload executes despite the protocol bypass.Impact
Predicate-based allowlisting bypasses DOMPurify's URI validation, allowing unsafe protocols such as
javascript:to reach the DOM and execute whenever the link is activated, resulting in DOM-based XSS.Credits
Identified by Cantina’s Apex (https://www.cantina.security).
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
DOMPurify's ADD_TAGS function form bypasses FORBID_TAGS due to short-circuit evaluation
GHSA-39q2-94rc-95cp
More information
Details
Summary
In
src/purify.ts:1117-1123,ADD_TAGSas a function (viaEXTRA_ELEMENT_HANDLING.tagCheck) bypassesFORBID_TAGSdue to short-circuit evaluation.The condition:
When
tagCheck(tagName)returnstrue, the entire condition isfalseand the element is kept —FORBID_TAGS[tagName]is never evaluated.Inconsistency
This contradicts the attribute-side pattern at line 1214 where
FORBID_ATTRexplicitly wins first:For tags, FORBID should also take precedence over ADD.
Impact
Applications using both
ADD_TAGSas a function andFORBID_TAGSsimultaneously get unexpected behavior — forbidden tags are allowed through. Config-dependent but a genuine logic inconsistency.Suggested Fix
Check
FORBID_TAGSbeforetagCheck:Affected Version
v3.3.3 (commit 883ac15)
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
DOMPurify: Prototype Pollution to XSS Bypass via CUSTOM_ELEMENT_HANDLING Fallback
CVE-2026-41238 / GHSA-v9jr-rg53-9pgp
More information
Details
Summary
DOMPurify versions 3.0.1 through 3.3.3 (latest) are vulnerable to a prototype pollution-based XSS bypass. When an application uses
DOMPurify.sanitize()with the default configuration (noCUSTOM_ELEMENT_HANDLINGoption), a prior prototype pollution gadget can inject permissivetagNameCheckandattributeNameCheckregex values intoObject.prototype, causing DOMPurify to allow arbitrary custom elements with arbitrary attributes — including event handlers — through sanitization.Affected Versions
Object.create(null)for initialization, no|| {}reassignment)|| {}reassignment was introduced in the 3.0.0→3.0.1 refactorRoot Cause
In
purify.jsat line 590, during config parsing:When no
CUSTOM_ELEMENT_HANDLINGis specified in the config (the default usage pattern),cfg.CUSTOM_ELEMENT_HANDLINGisundefined, and the fallback{}is used. This plain object inherits fromObject.prototype.Lines 591-598 then check
cfg.CUSTOM_ELEMENT_HANDLING(the original config property) — which isundefined— so the conditional blocks that would settagNameCheckandattributeNameCheckfrom the config are never entered.As a result,
CUSTOM_ELEMENT_HANDLING.tagNameCheckandCUSTOM_ELEMENT_HANDLING.attributeNameCheckresolve via the prototype chain. If an attacker has pollutedObject.prototype.tagNameCheckandObject.prototype.attributeNameCheckwith permissive values (e.g.,/.*/), these polluted values flow into DOMPurify's custom element validation at lines 973-977 and attribute validation, causing all custom elements and all attributes to be allowed.Impact
DOMPurify.sanitize(userInput)call is affected.Proof of Concept
Tested configurations that are vulnerable:
DOMPurify.sanitize(input)DOMPurify.sanitize(input, {})DOMPurify.sanitize(input, { CUSTOM_ELEMENT_HANDLING: null })DOMPurify.sanitize(input, { CUSTOM_ELEMENT_HANDLING: {} })Suggested Fix
Change line 590 from:
To:
The
create(null)function (already used elsewhere in DOMPurify, e.g., inclone()) creates an object with no prototype, preventing prototype chain inheritance.Alternative application-level mitigation:
Applications can protect themselves by always providing an explicit
CUSTOM_ELEMENT_HANDLINGin their config:Timeline
Credit
https://github.com/trace37labs
Severity
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
DOMPurify has a SAFE_FOR_TEMPLATES bypass in RETURN_DOM mode
CVE-2026-41239 / GHSA-crv5-9vww-q3g8
More information
Details
Summary
mainat883ac15, introduced in v1.0.10 (7fc196db)SAFE_FOR_TEMPLATESstrips{{...}}expressions from untrusted HTML. This works in string mode but not withRETURN_DOMorRETURN_DOM_FRAGMENT, allowing XSS via template-evaluating frameworks like Vue 2.Technical Details
DOMPurify strips template expressions in two passes:
purify.ts:1179-1191):purify.ts:1679-1683). This is the safety net that catches expressions that only form after the DOM settles.The
RETURN_DOMpath returns before pass #2 ever runs (purify.ts:1637-1661):The payload
{<foo></foo>{constructor.constructor('alert(1)')()}<foo></foo>}exploits this:TEXT("{")→<foo>→TEXT("{payload}")→<foo>→TEXT("}")— no single node contains{{, so pass #1 misses it<foo>is not allowed, so DOMPurify removes it but keeps surrounding text.outerHTMLreads them as{{payload}}, which Vue 2 compiles and executesReproduce
Open the following html in any browser and
alert(1)pops up.Impact
Any application that sanitizes attacker-controlled HTML with
SAFE_FOR_TEMPLATES: trueandRETURN_DOM: true(orRETURN_DOM_FRAGMENT: true), then mounts the result into a template-evaluating framework, is vulnerable to XSS.Recommendations
Fix
normalize()merges the split text nodes, then the same regex from the string path catches the expression. Placed before the fragment logic, this fixes bothRETURN_DOMandRETURN_DOM_FRAGMENT.if (RETURN_DOM) { + if (SAFE_FOR_TEMPLATES) { + body.normalize(); + let html = body.innerHTML; + arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr: RegExp) => { + html = stringReplace(html, expr, ' '); + }); + body.innerHTML = html; + } + if (RETURN_DOM_FRAGMENT) { returnNode = createDocumentFragment.call(body.ownerDocument);Severity
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
DOMPurify: FORBID_TAGS bypassed by function-based ADD_TAGS predicate (asymmetry with FORBID_ATTR fix)
CVE-2026-41240 / GHSA-h7mw-gpvr-xq4m
More information
Details
There is an inconsistency between FORBID_TAGS and FORBID_ATTR handling when function-based ADD_TAGS is used.
Commit c361baa added an early exit for FORBID_ATTR at line 1214:
The same fix was not applied to FORBID_TAGS. At line 1118-1123, when EXTRA_ELEMENT_HANDLING.tagCheck returns true, the short-circuit evaluation skips the FORBID_TAGS check entirely:
This allows forbidden elements to survive sanitization with their attributes intact.
PoC (tested against current HEAD in Node.js + jsdom):
Confirmed affected: iframe, object, embed, form. The src/action/data attributes survive because attribute sanitization runs separately and allows these URLs.
Compare with FORBID_ATTR which correctly wins:
Suggested fix: add FORBID_TAGS early exit before the tagCheck evaluation, mirroring line 1214:
This requires function-based ADD_TAGS in the config, which is uncommon. But the asymmetry with the FORBID_ATTR fix is clear, and the impact includes iframe and form injection with external URLs.
Reporter: Koda Reef
Severity
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:H/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
cure53/DOMPurify (dompurify)
v3.4.0: DOMPurify 3.4.0Compare Source
Most relevant changes:
FORBID_TAGSnot winning overADD_TAGS, thanks @kodareef5ADD_ATTR/ADD_TAGSfunction leaking into subsequent array-based calls, thanks @1Jesper1SAFE_FOR_TEMPLATESscrub inRETURN_DOMpath, thanks @bencalifCUSTOM_ELEMENT_HANDLING, thanks @trace37labsADD_TAGSfunction form bypassingFORBID_TAGS, thanks @eddieranADD_ATTRpredicates skipping URI validation, thanks @christos-ethUSE_PROFILESprototype pollution, thanks @christos-ethPublished Advisories are here:
https://github.com/cure53/DOMPurify/security/advisories?state=published
v3.3.3: DOMPurify 3.3.3Compare Source
v3.3.2: DOMPurify 3.3.2Compare Source
_isValidAttribute, thanks @christos-ethConfiguration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.
This PR was generated by Mend Renovate. View the repository job log.