CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-c2j3-45gr-mqc4: DOMPurify: `CUSTOM_ELEMENT_HANDLING` bypasses `afterSanitizeElements` for allowed custom elements.

low
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 through afterSanitizeElements in the same way as a normal element. As a result, an application that relies on afterSanitizeElements as 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~1691 const _sanitizeDisallowedNode = function ( currentNode: any, tagName: string ): boolean { /* Check if we have a custom element to handle */ if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) { if ( CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName) ) { return false; } if ( CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName) ) { return false; } } CUSTOM_ELEMENT_HANDLING is parsed from user configuration at src/purify.ts: line 741~748 const customElementHandling = objectHasOwnProperty(cfg, 'CUSTOM_ELEMENT_HANDLING') && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === 'object' ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null); CUSTOM_ELEMENT_HANDLING = create(null); In particular, tagNameCheck, attributeNameCheck, and allowCustomizedBuiltInElements are copied into the internal CUSTOM_ELEMENT_HANDLING object there. During element sanitization, _sanitizeElements() checks

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
low
Published
2026-07-21
Last updated
2026-07-21
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-c2j3-45gr-mqc4

More from GitHub Security Advisories