Sep 25, 2026·7 min read·3 visits
The xhtml-purifier library does not encode double quotes in attribute values during re-serialization, allowing attackers to inject malicious HTML attributes like event handlers and execute arbitrary JavaScript.
A critical sanitizer bypass vulnerability exists in the xhtml-purifier Node.js library prior to version 0.4.3. Due to a lack of HTML entity encoding during the attribute re-serialization phase, unauthenticated remote attackers can break out of double-quoted attribute contexts to inject arbitrary script handlers, resulting in Cross-Site Scripting.
The Node.js library xhtml-purifier (developed by cstigler) is designed to take raw, untrusted HTML input and sanitize it into compliant, safe XHTML or HTML output. This library is commonly integrated into web applications to allow safe user-generated content, such as blog comments, forum posts, or formatted text. The library utilizes an internal parsing mechanism to analyze elements and ensure only pre-approved tags and attributes exist in the output.
However, in versions prior to 0.4.3, xhtml-purifier fails to perform appropriate encoding on attribute values during its final serialization phase. Although the parser successfully limits elements to whitelisted attributes, it does not sanitize the contents of those attributes against context-breaking characters. This allows attackers to supply custom payloads inside permitted attributes to modify the structural syntax of the output document.
The resulting vulnerability is classified under CWE-79 (Improper Neutralization of Input During Web Page Generation) and CWE-116 (Improper Encoding or Escaping of Output). Because the injection happens during serialization after the parsing and validation phases have concluded, the injected characters bypass the sanitization filters entirely. This leads to a reliable stored or reflected cross-site scripting (XSS) vulnerability depending on how the application processes and displays the output.
The core vulnerability lies within the re-serialization phase of xhtml-purifier, specifically inside the attributeString() function located in XHTMLPurifier.js. When the library processes HTML, it converts the raw input into an in-memory tree representation. During this tree construction, the parser identifies whitelisted attributes, such as class, style, or title, and captures their corresponding values as literal string data without validation of special formatting characters.
During the serialization stage, the library recreates the sanitized HTML markup by iterating over the attributes and reconstructing the tags. The function outputs these values by concatenating the raw attribute value straight into double-quoted structures: string += " " + name + "=\"" + value + "\"";. Since the library does not search for, escape, or entity-encode the double-quote (") character inside the value variable, any double-quote within a permitted attribute will successfully terminate the attribute scope in the output string.
Consequently, an attacker who injects a double-quote into an allowed attribute value can append arbitrary characters that will be interpreted as new attributes by a browser. Because the input parser already validated the parent attribute as safe, the injected content bypasses the tag-stripping logic. The downstream browser parser processes the unescaped double-quote, terminates the whitelisted attribute, and interprets the malicious payload as valid, active attributes on the same tag.
The vulnerability is highlighted when analyzing the code before the patch in XHTMLPurifier.js around line 148. The original serialization loop concatenates raw values directly without filtering:
// Vulnerable Code Path in XHTMLPurifier.js
for (var name in attributes) {
var value = attributes[name];
// ... validation logic
string += " " + name + "=\"" + value + "\"";
}To resolve this issue, the developer modified the serialization logic in commit 21d461ad23e7bc9b3073693d5b51b9b8662044d3 to implement robust escaping. The following code fragment shows the introduced changes:
// Patched Code Path in XHTMLPurifier.js
var encodedValue = String(value)
.replace(/&(?![a-zA-Z][a-zA-Z0-9]*;|#\d+;|#x[0-9a-fA-F]+;)/g, "&")
.replace(/"/g, """)
.replace(/</g, "<")
.replace(/>/g, ">");
string += " " + name + "=\"" + encodedValue + "\"";This remediation ensures that any instance of a double-quote character is transformed into its corresponding safe HTML entity ("). Additionally, the patch includes escaping for less-than (<) and greater-than (>) signs to prevent premature element closure. The regular expression for ampersands uses a negative lookahead to avoid re-encoding already valid, well-formed HTML entities, preserving application behavior while protecting against bypass vectors.
Exploitation of CVE-2026-61784 requires the target application to utilize a vulnerable version of xhtml-purifier to sanitize untrusted user input and subsequently render the output to users. The attacker must target a whitelisted HTML element and attribute to prevent the initial parser from dropping the entire node. Attributes such as class, title, or style are suitable candidates for this vector.
The attacker crafts a payload that embeds double quotes inside a single-quoted HTML tag. When processed by xhtml-purifier, the parser accepts the overall element and parses the inner content as the value of the whitelisted attribute. An example payload format is structured as follows:
<span class='test" onmouseover="javascript:alert(document.cookie)' style='color:red;'>Hover here</span>When the serialization logic executes, the resulting HTML string emitted by the library is structured as:
<span class="test" onmouseover="javascript:alert(document.cookie)" style="color:red;">Hover here</span>When this output is loaded by the victim's browser, the parser recognizes onmouseover as a valid event handler attribute of the span element. Once a victim interacts with the element, the javascript payload is executed in the context of the vulnerable origin. This allows the attacker to execute arbitrary script, steal session cookies, or manipulate the page structure.
The impact of CVE-2026-61784 is assessed with a CVSS v3.1 base score of 6.1 (Medium). The attack vector is Network, meaning exploitation can occur remotely without local access requirements. The attack complexity is Low, as the payload relies on basic HTML structures and requires no specialized configuration or timing. No privileges are required to exploit the flaw, but User Interaction is required for the payload to be rendered and triggered in a browser context.
The potential impact on confidentiality is Low, as the executing script can read sensitive DOM data, session tokens, or other client-side information. Similarly, the impact on integrity is Low because the injected code can execute requests or modify application state on behalf of the victim. There is no direct impact on availability.
While categorized as Medium, the impact scales significantly if the application handles privileged administrative sessions. A successful cross-site scripting attack against an administrative user could lead to complete administrative takeover of the backend platform, illustrating how client-side bypasses can act as primary entry points for more severe downstream compromises.
The primary remediation path is upgrading the xhtml-purifier dependency to version 0.4.3 or later. This version contains the updated serialization engine that correctly entity-encodes attribute values. Organizations utilizing automated package managers should update their definitions to exclude vulnerable versions.
To detect potential exploitation attempts at the network or application layer, security teams can employ custom rules. Web Application Firewalls (WAF) can be configured to detect attribute breakout attempts within JSON or form inputs that contain HTML. For example, patterns looking for double quotes followed immediately by event handlers inside single-quoted elements can identify active payloads.
# Example detection pattern concept for WAF or input filtering
(?i)<\w+\s+[^>]*\s*=\s*['"][^'"]*["'][^>]*\s+on[a-z]+=
Organizations should also conduct automated dependency audits using tools like npm audit or static application security testing (SAST) to discover instances of the library across all active codebases. If immediate upgrading is impossible, a temporary workaround involves manually stripping or sanitizing double quotes from input strings before passing them to the purifier library.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
xhtml-purifier cstigler | < 0.4.3 | 0.4.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 |
| Attack Vector | Network |
| CVSS Score | 6.1 (Medium) |
| EPSS Score | 0.00168 |
| Impact | Sanitizer Bypass / Cross-Site Scripting (XSS) |
| Exploit Status | PoC / Functional Tests available |
| CISA KEV Status | Not Listed |
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
A critical logical vulnerability in the FriendsOfFlarum OAuth (fof/oauth) extension allows unauthenticated remote attackers to perform complete account takeover, including administrative profiles. This vulnerability is caused by a failure to verify the email verification status returned by third-party identity providers such as Discord before asserting that the email is trusted and matching it to existing local accounts.
CVE-2026-61741 is a critical XML External Entity (XXE) injection vulnerability in the http4s-scala-xml library. The vulnerability allows remote, unauthenticated attackers to perform arbitrary local file disclosure, execute server-side request forgery (SSRF) attacks, or cause denial of service via recursive entity expansion. The vulnerability stems from the use of an unconfigured SAXParserFactory, which enables external entity resolution by default.
A critical DNS rebinding vulnerability in DBHub (associated with GHSA-fm8p-53ww-hf6w) allows unauthenticated remote attackers to execute arbitrary SQL queries against local and internal databases. By exploiting a relative origin validation check within the HTTP transport middleware, an attacker can bypass same-origin protections via DNS rebinding. This allows malicious external websites to send JSON-RPC commands to the local DBHub service to read, write, and exfiltrate database contents. The issue affects all versions of DBHub prior to 0.22.5.
CVE-2026-61788 identifies a critical vulnerability in DBHub, an open-source database Model Context Protocol (MCP) server designed to manage and interact with database engines including PostgreSQL, MySQL, SQL Server, Oracle, MariaDB, and SQLite. Prior to version 0.22.6, DBHub fails to securely enforce its declared 'readonly' execution mode. Unauthenticated remote attackers can bypass keyword-based filters and transaction controls to execute arbitrary write operations, manipulate database sequences, read or write files on the host operating system, and potentially execute arbitrary system commands.
Cilium, a cloud-native networking and security solution for Kubernetes, contains a security bypass vulnerability in its translation engine for Gateway API resources. When parsing HTTPRoute and GRPCRoute configurations, the Cilium Operator fails to apply ReferenceGrant authorization checks to RequestMirror filters. This flaw allows a user with restricted namespace-level permissions to mirror and route traffic to services across namespace boundaries without authorization, leading to cross-namespace data leaks.
CVE-2026-57231 is a high-severity vulnerability in the Podman container engine. When executing a container from a crafted OCI or Docker image, malformed environment variable entries lacking an equals separator can trigger an unexpected behavior in the spec generation parser. This vulnerability enables a container image to silently exfiltrate host environment variables into the running container workspace, exposing high-privilege credentials and sensitive runtime secrets.