chore(deps): update dependency dompurify to v3.4.12 [security] (stable33)#3297
Open
renovate[bot] wants to merge 1 commit into
Open
chore(deps): update dependency dompurify to v3.4.12 [security] (stable33)#3297renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
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.4.0→3.4.12DOMPurify:
CUSTOM_ELEMENT_HANDLINGbypassesafterSanitizeElementsfor allowed custom elements.GHSA-c2j3-45gr-mqc4
More information
Details
Summary
There is a possible hook-policy inconsistency in DOMPurify 3.4.11 involving
CUSTOM_ELEMENT_HANDLING.When a custom element is allowed via
CUSTOM_ELEMENT_HANDLING.tagNameCheck, it appears that the element does not go throughafterSanitizeElementsin the same way as a normal element. As a result, an application that relies onafterSanitizeElementsas a security policy layer to strip sensitive attributes from all elements may see those attributes removed from normal elements but preserved on allowed custom elements.This does not appear to be a direct DOMPurify XSS or a case where DOMPurify directly allows executable payloads. The preserved value is still inert at sanitize time. The issue becomes relevant when the allowed custom element later re-injects that attribute value into an HTML sink such as
innerHTML, creating a second-order XSS gadget.Details
The issue appears to originate from the control flow in
src/purify.ts: line 1672~1691CUSTOM_ELEMENT_HANDLINGis parsed from user configuration atsrc/purify.ts: line 741~748In particular,
tagNameCheck,attributeNameCheck, andallowCustomizedBuiltInElementsare copied into the internalCUSTOM_ELEMENT_HANDLINGobject there.During element sanitization,
_sanitizeElements()checks whether a node is forbidden or not allowlisted atsrc/purify.ts: line 1805~1814If so, it immediately delegates to
_sanitizeDisallowedNode(currentNode, tagName)and returns its boolean result.Inside
_sanitizeDisallowedNode(), the custom-element-specific allow path is implemented atsrc/purify.ts: line 1672~1692If the node is treated as a basic custom element and
CUSTOM_ELEMENT_HANDLING.tagNameCheckmatches, the function returnsfalseimmediately at line 1682 or 1689, meaning “do not remove this node”.That early
return falseis significant because control returns directly to_sanitizeElements()via thereturn _sanitizeDisallowedNode(...)at line 1813. As a result, the later logic in_sanitizeElements()is skipped for that custom element instance, including:src/purify.ts: line 1816~1826src/purify.ts: line 1828~1837afterSanitizeElementshook dispatch atsrc/purify.ts: line 1850~1851.In other words, a normal allowlisted element continues through
_sanitizeElements()and reacheshooks.afterSanitizeElements, but a disallowed-by-default element that is revived by theCUSTOM_ELEMENT_HANDLING.tagNameCheckpath does not. This creates a policy inconsistency: an application that relies onafterSanitizeElementsto remove an attribute from all elements will observe that the policy is applied to normal elements but not to custom elements allowed throughCUSTOM_ELEMENT_HANDLING.In the PoC, the application hook removes
data-biofrom ordinary elements, but the same attribute remains on<x-bio>because the custom-element keep path bypassesafterSanitizeElements. The attribute itself is inert at sanitize time and DOMPurify is not directly allowing executable SVG/HTML through. The security impact appears when the application-defined custom element later reads the preserveddata-biovalue inconnectedCallback()and writes it toinnerHTML, turning the preserved attribute into a second-order XSS gadget.PoC
Reproduced on DOMPurify 3.4.11.
Steps
poc.html.divcontrol losesdata-bio, while the allowed custom element keeps it.connectedCallback()runs, the candidate payload is reinserted into the DOM and executes through the custom element’s own sink.HTML PoC
Expected result
This is output of HTML PoC.
Impact
This does not appear to affect DOMPurify’s default configuration as a direct sanitizer bypass.
The impact is limited to applications that:
CUSTOM_ELEMENT_HANDLING,afterSanitizeElementsas a security policy layer,innerHTMLor another HTML sink.In that situation, the behavior can become a second-order XSS gadget because a security-relevant attribute is removed from normal elements but remains on allowed custom elements.
Possible fixes or mitigations might include
afterSanitizeElementsCUSTOM_ELEMENT_HANDLINGmay not participate in the same post-element hook flow as normal allowlisted elements.Severity
CVSS:4.0/AV:N/AC:H/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).
Release Notes
cure53/DOMPurify (dompurify)
v3.4.12: DOMPurify 3.4.12Compare Source
v3.4.11: DOMPurify 3.4.11Compare Source
setConfig, thanks @trace37labsnpm auditosv-scannersuppression list as no vulnerable dependencies are left for nowv3.4.10: DOMPurify 3.4.10Compare Source
types.tsSAFE_FOR_TEMPLATESscrubbing into single shared pathtextContentbeforeinnerHTMLnpm run bench) with a--comparemodedemos/folder so every demo runs again, and added a SVG-via-<img>demotest:happydomscripts in the READMEv3.4.9: DOMPurify 3.4.9Compare Source
IN_PLACEsanitization, thanks @mozfreddybIN_PLACEand Trusted Types related usagev3.4.8: DOMPurify 3.4.8Compare Source
v3.4.7: DOMPurify 3.4.7Compare Source
IN_PLACE, thanks @GameZoneHackerv3.4.6: DOMPurify 3.4.6Compare Source
IN_PLACEmode, thanks @offset & @BankdeIN_PLACEand Shadow DOM sanitization, thanks @offset & @BankdeIN_PLACEand general DOM Clobbering attacksv3.4.5: DOMPurify 3.4.5Compare Source
selectedcontentadded in 3.4.4, thanks @KabirAcharyaNote that this is a security release for an issue introduced in 3.4.4 and should be upgraded to immediately.
v3.4.4: DOMPurify 3.4.4Compare Source
selectedcontentelement to default allow-list, thanks @lukewarlowcommandandcommandforattributes to default allowed-list, thanks @lukewarlowIN_PLACEoperations, thanks @DEMON1A🚨 This release had been flagged as deprecated, please use DOMPurify 3.4.5 instead 🚨
v3.4.3: DOMPurify 3.4.3Compare Source
v3.4.2: DOMPurify 3.4.2Compare Source
ADD_ATTRcallback, thanks @nelstromv3.4.1: DOMPurify 3.4.1Compare Source
font-face,color-profile,missing-glyph,font-face-src,font-face-uri,font-face-format,font-face-name) under permissiveCUSTOM_ELEMENT_HANDLINGannotation-xmlcheck that allowed mixed-case variants to bypass the basic-custom-element exclusion in XHTML modeSANITIZE_NAMED_PROPSrepeatedly prefixing already-prefixedidandnamevalues on subsequent sanitizationIN_PLACEroot-node check to explicitly guard against non-stringnodeName(DOM-clobbering robustness)slotentry from the default HTML attribute allow-listSANITIZE_NAMED_PROPS, and a negative-control assertion ensuring the invariants actually fireSAFE_FOR_TEMPLATESgreedy scrub, hook-added attribute handling)3.xand2.xmaintenance branchesConfiguration
📅 Schedule: (in timezone Europe/Berlin)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.