Skip to content

[Vulnerability] cure53/DOMPurify: XSS / Security Policy Bypass #180

Description

@github-actions

Potential Security Vulnerability Detected

Repository: cure53/DOMPurify
Commit: 9f0a07d
Author: Cure53
Date: 2026-07-11T11:23:47Z

Commit Message

fix: addressed an issue with hook-handling for CE sanitization (#1527)

* fix: addressed an issue with hook-handling for CE sanitization, thanks @Rikuxx0

* chore: rebuild dist to sync purify.min.js + sourcemaps after main merge

Pull Request

PR: #1527 - fix: addressed an issue with hook-handling for CE sanitization
Labels: None

Description:
See above

Analysis

Vulnerability Type: XSS / Security Policy Bypass
Severity: High

Description

Custom elements allowed via CUSTOM_ELEMENT_HANDLING were not having the afterSanitizeElements hook executed on them. Before the patch, _sanitizeDisallowedNode returned false for kept custom elements and the caller immediately returned that value, skipping the afterSanitizeElements hook entirely. This meant any security policy applied in that hook (e.g., stripping dangerous attributes from every surviving element) silently skipped kept custom elements, potentially allowing malicious attributes or content to survive sanitization.

Affected Code

if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
  return _sanitizeDisallowedNode(currentNode, tagName);
}

Proof of Concept

const DOMPurify = createDOMPurify(window);
// Configure a custom element to be allowed
DOMPurify.setConfig({
  CUSTOM_ELEMENT_HANDLING: {
    tagNameCheck: /^my-element$/,
    attributeNameCheck: /.*/,
    allowCustomizedBuiltInElements: false
  }
});
// Add a hook that should strip all onclick attributes from every surviving element
DOMPurify.addHook('afterSanitizeElements', function(node) {
  if (node.removeAttribute) node.removeAttribute('onclick');
});
// Before the patch, the hook is NOT called for kept custom elements,
// so onclick survives on <my-element>
const result = DOMPurify.sanitize('<my-element onclick="alert(1)">test</my-element>');
// result still contains onclick="alert(1)" - hook was bypassed

This issue was automatically created by Vulnerability Spoiler Alert.
Detected at: 2026-07-11T13:12:34.074Z

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions