Skip to main content

xhtml-purifier EUVDEUVD-2026-86325

| CVE-2026-61784 MEDIUM
Cross-site Scripting (XSS) (CWE-79)
2026-09-24 GitHub_M GHSA-j8r4-32c5-33rc
6.1
CVSS 3.1 · Vendor: GitHub_M
View

Attack ChainAIDerived

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

  1. Access
    Craft HTML with quote-breaking attribute value
  2. Delivery
    Submit to app using xhtml-purifier
  3. Exploit
    Sanitizer serializes value unencoded
  4. Execution
    Injected onmouseover/onerror handler survives output
  5. Persist
    Victim renders/interacts with content
  6. Impact
    Arbitrary JS runs in victim session

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 target application (1) uses node-xhtml-purifier at a version below 0.4.3, (2) passes attacker-controlled HTML through it for sanitization, and (3) renders the purified output in a browser. The attacker must be able to inject a double-quote character into any allowed attribute value (class, style, title, alt, src, or href); the resulting breakout attaches an event handler (e.g., onmouseover, onerror). The primary limiting factor is UI:R - the victim must render and, for handlers like onmouseover, interact with (hover over) the malicious element for the script to fire; onerror-based payloads fire on load. There is no authentication requirement (PR:N), but exploitation is entirely contingent on an application actually adopting this specific niche sanitizer.

Impact

This is a genuine sanitizer bypass but a moderate-priority issue overall. The CVSS 3.1 base score of 6.1 (AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N) reflects a classic stored/reflected XSS: network-reachable, low complexity, no privileges, but requiring user interaction (UI:R) and yielding only partial confidentiality/integrity impact with a scope change (the injected script executes in the victim's browser origin, a different security scope than the sanitizer library). No EPSS score, KEV listing, or SSVC decision data was provided, and no public exploit code was supplied - the diff includes only a unit test, not a weaponized PoC, so this is 'no public exploit identified at time of analysis.' The real-world risk is bounded primarily by prevalence: node-xhtml-purifier is an obscure single-maintainer npm library, so despite the CVSS being unauthenticated-network the practical blast radius is small and depends entirely on how many applications actually use this specific sanitizer to render attacker-supplied HTML. The vulnerability class (attribute-injection XSS via unencoded double-quotes) is well understood and the root cause is confirmed by the vendor advisory and the fix commit, so the technical claim is solid; the aggregate exploitation likelihood is low-to-moderate given niche deployment.

Exploit ScenarioDerived

An application uses node-xhtml-purifier (<0.4.3) to sanitize user-submitted HTML (e.g., forum posts, comments, profile fields) before rendering it. An attacker submits content where an allowed attribute value contains a double-quote - for example an href or class value like c" onmouseover="alert(1) - which survives sanitization unencoded, breaks out of the quoted attribute, and injects a live event handler that executes JavaScript in the victim's browser when they view or hover over the content. No public exploit code exists, but the technique is trivial and demonstrated by the vendor's own regression test.

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

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

Alert me

AnalysisAIv1 – Sep 24, 2026

Attribute-injection cross-site scripting in xhtml-purifier (npm package node-xhtml-purifier) before 0.4.3 lets an attacker who can supply HTML to the sanitizer smuggle a JavaScript event handler - for example onmouseover or onerror - past purification so that it executes when the purified output is rendered in a browser. The serializer in XHTMLPurifier.js writes each attribute value straight into a double-quoted attribute without HTML-entity encoding, so a double quote inside any allowed attribute (class, style, title, alt, src, href) terminates the attribute and starts a new one, converting data into markup. The CVSS vector (AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N, score 6.1) indicates no authentication requirement but a user-interaction prerequisite, since the victim must render the output and, for handlers like onmouseover, trigger the element; this is a genuine sanitizer bypass but a moderate-priority issue overall, and exploitation is contingent on an application actually passing attacker-controlled HTML through this niche library. No public exploit code and no confirmed active exploitation were identified at time of analysis.

RemediationAI

Vendor-released patch: 0.4.3 - upgrade xhtml-purifier to 0.4.3 or later in package.json and regenerate the lockfile so the fixed serializer (commit 21d461ad23e7bc9b3073693d5b51b9b8662044d3) is actually installed; the advisory at https://github.com/cstigler/node-xhtml-purifier/security/advisories/GHSA-j8r4-32c5-33rc accompanies the release. If an immediate upgrade is not possible, treat the sanitizer itself as untrusted output: HTML-entity-encode attribute values a second time after purification, or reject/normalize any double quote inside allowed attribute values before the HTML reaches the purifier, accepting that legitimate values containing quotes (for example a title string) may be mangled and that this is a brittle, easily bypassed stopgap rather than a real fix. Because the failure is in the sanitizer's serialization layer, the more robust compensating control is to replace this niche library with an actively maintained sanitizer such as DOMPurify or sanitize-html for the same rendering path, which carries the migration cost of re-validating the allow-list against your content requirements. No public exploit code was identified, so no additional network-level filtering is warranted beyond normal content-security-policy hardening.

Affected VersionsENISA

node-xhtml-purifier < 0.4.3

Affected Packages

npm xhtml-purifier fix: 0.4.3
euvd node_xhtml_purifier fix: 0.4.3

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 2 packages in npm, euvd

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

Technical ContextAI · show details

xhtml-purifier is a lightweight Node.js HTML sanitizer that parses raw, untrusted HTML and re-serializes only an allow-listed subset of tags and attributes, acting as a trust boundary between untrusted input and browser rendering. The flaw is a classic output-encoding defect (CWE-79, improper neutralization of input during web page generation) located in the attributeString() method of XHTMLPurifier.js around line 148: sanitization correctly restricts which attributes are permitted, but the subsequent serialization concatenates the raw attribute value into a double-quoted attribute without escaping the ampersand, double quote, or angle brackets. Because the parser's clean value is never re-encoded for the HTML attribute context, a value containing a double quote escapes the quoting and introduces an attacker-chosen attribute, including event handlers, that the sanitizer does not strip because the handler was never a parsed attribute in the first place. The 0.4.3 fix replaces that concatenation with an entity-encoding step that converts '&' (when not already part of an entity), '"', '<' and '>' into &amp;, &quot;, &lt; and &gt; respectively, and the accompanying test asserts that an embedded quote is emitted as &quot; and that no live on* handler appears in the output. The affected component is identified by CPE cpe:2.3:a:cstigler:node-xhtml-purifier:*:*:*:*:*:*:*:*, covering the package's releases prior to 0.4.3.

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 (GitHub_M) PRIMARY 6.1 MEDIUM
AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
vuln.today AI 6.1 MEDIUM

Standard sanitizer-bypass XSS: network attacker-supplied input, no auth, requires victim to render/interact (UI:R), scope change into browser origin (S:C), partial C/I impact in victim session.

3.1 AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
4.0 AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N

Primary rating from Vendor (GitHub_M).

CVSS VectorVendor: GitHub_M

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Changed
Confidentiality
Low
Integrity
Low
Availability
None

Lifecycle Timeline

1
Patch available
Sep 24, 2026 - 19:04 EUVD

DescriptionCVE.org

xhtml-purifier is a Node.js library to take in raw/unknown/untrusted HTML and output cleaned, purified, trusted HTML. Versions prior to 0.4.3 do not HTML-entity-encode attribute values when serializing its sanitized output. In attributeString() (XHTMLPurifier.js, around line 148) the attribute value is concatenated directly into a double-quoted attribute without encoding. As a result, an attacker-controlled value in any allowed attribute (class, style, title, alt, src, href) can include a double-quote character to break out of the attribute and inject an additional attribute, such as a JavaScript event handler (for example onmouseover or onerror). The injected handler survives sanitization and executes when the output is rendered, which is a sanitizer bypass leading to cross-site scripting. The fix in version 0.4.3 HTML-entity-encodes attribute values before serialization.

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 3 npm packages depend on xhtml-purifier (3 direct, 0 indirect)

Ecosystem-wide dependent count for version 0.4.3.

Threat Intelligence Overview

EPSS Score
0.2%
Top 95% exploitable
Prevalence
Low
obscure single-maintainer npm HTML-sanitizer library, small deployment footprint
Threat Intel
1
1 source
Exploit
POC
Public exploit code exists
Data Quality
6 sources
Confidence: High
EUVD NVD CVE.org EPSS Vulnrichment GHSA GitHub

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 Yes
EPSS 0.2%
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
None
System Exposure· derived
Open
Automatable
No
Human Impact· derived
Medium
Technical Impact
Partial

Priority Score

50
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +30
PoC: +20
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.

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-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

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