Cloudanix VulnDB

CVE-2026-41238

Medium · 6.9

CVSS

6.9

EPSS

0.3%

Published

Apr 23, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

Some websites using affected versions of a common HTML-cleaning library may accidentally let malicious web code run if another bug first tampers with how the browser handles objects.

Chainable
Exploitation
Requires User Interaction
Attacker needs
User Interaction
Complexity
High
Impact
Data Exposure
Component
Library
Class
XSS
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

DOMPurify versions 3.0.1 through 3.3.3 can be bypassed when an application calls DOMPurify.sanitize() with its default configuration and the JavaScript runtime has already been affected by prototype pollution. If an attacker can pollute Object.prototype with permissive CUSTOM_ELEMENT_HANDLING-related properties such as tagNameCheck and attributeNameCheck, DOMPurify may treat attacker-controlled custom elements and attributes as allowed. This can let dangerous HTML attributes, including JavaScript event handlers, survive sanitization and execute in a victim browser. The vulnerability is not a standalone XSS primitive in most applications: exploitation generally requires both a reachable prototype pollution gadget and a place where sanitized attacker-controlled markup is later rendered into the DOM.

Why it matters to the business

Successful exploitation can allow attacker-supplied script to run in users’ browsers, which may expose session tokens, account data, user-visible content, or application actions performed as the victim. The CVSS score is moderate-high, but the practical likelihood is currently low because EPSS is low, no known CISA KEV listing exists, ransomware use is not reported, and exploitation requires a separate prototype pollution condition plus user interaction. Organizations with many web applications or downstream packages that embed DOMPurify should still treat this as important because sanitizer bypasses can turn otherwise contained HTML-rendering features into account compromise or data exposure paths.

How an attack unfolds

An attacker first identifies an application that both accepts or stores user-controlled HTML and uses DOMPurify 3.0.1 through 3.3.3 to sanitize it before rendering. The attacker then finds a separate prototype pollution path in the same browser-side execution context, commonly through unsafe object merge, query-string parsing, JSON handling, or deep assignment behavior that permits keys such as __proto__, constructor, or prototype. Through that gadget, the attacker injects permissive checks into Object.prototype so DOMPurify’s default CUSTOM_ELEMENT_HANDLING behavior resolves attacker-controlled tagNameCheck and attributeNameCheck values. The attacker then submits markup using custom elements and attributes that would normally be removed, such as event-handler attributes. When a victim views or interacts with the affected content, the polluted prototype influences DOMPurify’s allow-list decision, the unsafe attribute remains in the sanitized output, and the browser executes attacker-controlled JavaScript in the application origin.

How to fix it

Upgrade DOMPurify to version 3.4.0 or later everywhere it is bundled, including direct dependencies, transitive dependencies, vendored JavaScript, CDN references, and prebuilt frontend assets. Rebuild and redeploy applications after dependency updates so the fixed sanitizer code is actually shipped to browsers. If immediate upgrade is not possible, reduce exposure by explicitly configuring strict CUSTOM_ELEMENT_HANDLING, avoiding permissive custom element or attribute checks, and preventing polluted inherited properties from influencing sanitizer configuration. Also remediate any prototype pollution gadgets in the application, because this vulnerability depends on a polluted prototype state. Apply defense-in-depth controls such as Content Security Policy without unsafe-inline, output encoding appropriate to the rendering context, avoiding insertion of sanitized HTML with unnecessary privileges, and limiting user-controlled rich-text features where possible.

How to confirm the fix worked

Confirm dependency inventories, lockfiles, package manifests, bundled assets, and software composition analysis results show DOMPurify 3.4.0 or later and no remaining 3.0.1 through 3.3.3 copies. Inspect generated frontend bundles and CDN references because older sanitizer versions may remain after package updates. Add a regression test that first simulates prototype pollution of Object.prototype with tagNameCheck and attributeNameCheck, then calls DOMPurify.sanitize() with default options against custom-element markup containing event handlers, and verify the unsafe attributes are removed. Validate browser behavior, not only server-side tests, because the issue occurs in DOM sanitization and rendering. Confirm CSP is active and does not allow broad inline script execution as a compensating control, while recognizing CSP is not a replacement for upgrading.

Typical attack path

  1. Find a web page or workflow that renders user-controlled HTML after calling DOMPurify.sanitize().
  2. Confirm the deployed DOMPurify version is between 3.0.1 and 3.3.3, or infer vulnerability from bundled JavaScript artifacts.
  3. Identify a client-side prototype pollution gadget reachable before sanitization occurs.
  4. Pollute Object.prototype with permissive custom element handling properties such as tagNameCheck and attributeNameCheck.
  5. Submit HTML containing custom elements with normally blocked attributes, including JavaScript event handlers.
  6. Trigger rendering of the sanitized content in a victim browser.
  7. Execute script in the application origin and use that access to read accessible data, perform actions as the user, or pivot to additional client-side attacks.

How to detect it

Look for evidence of both prototype pollution attempts and XSS payload delivery in web, API, CDN, WAF, reverse proxy, and application logs. Useful sources include request bodies, query strings, fragment-capturing telemetry where available, rich-text submission records, frontend error reporting, CSP violation reports, browser security telemetry, and EDR/browser process telemetry for suspicious post-XSS behavior. Search for prototype pollution keys such as __proto__, constructor.prototype, prototype, tagNameCheck, attributeNameCheck, and CUSTOM_ELEMENT_HANDLING appearing in URLs, JSON bodies, form posts, stored content, or client-side error traces. Also search stored user-generated HTML for custom elements with event-handler attributes that should normally be removed by DOMPurify. CSP reports showing blocked inline event handlers or unexpected script execution from pages that render sanitized content can be strong secondary evidence. There are no public threat actors or known exploitation campaigns reported for this CVE in the provided data, so detection should focus on behavioral artifacts rather than actor-specific infrastructure.

  • DOMPurify.sanitize(
  • CUSTOM_ELEMENT_HANDLING
  • tagNameCheck
  • attributeNameCheck
  • __proto__
  • constructor.prototype
  • constructor[prototype]
  • prototype[tagNameCheck]
  • prototype[attributeNameCheck]
  • __proto__[tagNameCheck]
  • __proto__[attributeNameCheck]
  • "tagNameCheck"
  • "attributeNameCheck"
  • "__proto__"
  • "constructor"
  • onerror=
  • onload=
  • onclick=
  • onmouseover=
  • onanimationstart=
  • <script
  • javascript:
  • customElements.define
  • violated-directive: script-src
  • script-src-attr
  • Refused to execute inline event handler

What your security team should do

  • Prioritize upgrading DOMPurify to 3.4.0 or later in all web applications and frontend bundles, especially those that render user-supplied rich text, comments, messages, profile content, CMS content, SVG, MathML, or HTML snippets.
  • Search dependency manifests, lockfiles, SBOMs, CDN references, and built JavaScript bundles for DOMPurify versions 3.0.1 through 3.3.3.
  • Review applications using DOMPurify.sanitize() with default options and any use of CUSTOM_ELEMENT_HANDLING, custom element allow-lists, or custom attribute allow-lists.
  • Hunt for and fix prototype pollution gadgets, particularly unsafe deep merge, object path assignment, query parsing, and JSON-to-object mapping behavior that accepts __proto__, constructor, or prototype keys.
  • Deploy or tighten Content Security Policy to reduce the blast radius of client-side script execution, avoiding unsafe-inline where operationally feasible.
  • Add automated tests that combine prototype pollution simulation with sanitizer bypass payloads so future dependency or configuration changes do not reintroduce the pattern.
  • Because EPSS is currently low and there is no known KEV or ransomware use, schedule remediation based on exposure: internet-facing, user-content-heavy, or high-trust applications should be fixed first.

The record

DOMPurify is a DOM-only cross-site scripting sanitizer for HTML, MathML, and SVG. Versions 3.0.1 through 3.3.3 are vulnerable to a prototype pollution-based XSS bypass. When an application uses `DOMPurify.sanitize()` with the default configuration (no `CUSTOM_ELEMENT_HANDLING` option), a prior prototype pollution gadget can inject permissive `tagNameCheck` and `attributeNameCheck` regex values into `Object.prototype`, causing DOMPurify to allow arbitrary custom elements with arbitrary attributes — including event handlers — through sanitization. Version 3.4.0 fixes the issue.

Affected packages

Ecosystem Package Introduced Fixed
npm dompurify 3.0.1 3.4.0

Related vulnerabilities