Outdated HTML Sanitizer Library Allows Malicious Scripts to Slip Through
Your website uses a popular library called DOMPurify to clean up user-submitted content before displaying it — think of it like a spam filter for dangerous code. A flaw in certain versions of this library means that filter can be tricked, allowing a specially crafted piece of text to sneak harmful scripts past it. This only matters if your site places user-submitted content inside specific HTML form areas (like text boxes), but if it does, the risk is real.
Business Impact And Actions
high urgencyBusiness Impact
If exploited, an attacker could run malicious code in a visitor's browser — potentially stealing login sessions, redirecting users, or performing actions on their behalf without their knowledge. This could expose your customers to harm and create compliance or data-breach liability for your business. The fix is a straightforward library update that your developer can complete in under an hour.
What To Do
- Ask your developer to upgrade DOMPurify to version 3.2.7 or later — this is the official fix and should take less than an hour.
- If your site uses DOMPurify version 2.x (2.5.3–2.5.8), ask your developer to migrate to the 3.x branch, as the 2.x line will not receive a patch.
- Ask your developer to check whether sanitized content is ever placed inside HTML text areas or similar form elements — this is the specific scenario where the vulnerability can be triggered.
- Consider asking your developer to add a Content Security Policy (CSP) header to your site as an extra safety net against script injection.
DOMPurify 3.1.3–3.2.6 / 2.5.3–2.5.8: XSS via Textarea Rawtext Bypass in SAFE_FOR_XML (CVE-2025-15599)
medium severity CVSS 6.1Vulnerability Explanation
DOMPurify's SAFE_FOR_XML regex failed to account for closing rawtext element tags (e.g., </textarea>) appearing inside HTML attribute values. When DOMPurify sanitizes such input, the closing tag survives the sanitization pass. If the sanitized output is then injected into a rawtext context in the DOM (e.g., inside a <textarea> element), the closing tag breaks out of that context, and any subsequent content — including attacker-controlled JavaScript — is interpreted as normal HTML and executed by the browser. The attack requires user interaction (the victim must load a page containing the crafted payload) and is network-delivered.
Root Cause
A missing validation rule in DOMPurify's SAFE_FOR_XML regex pattern did not escape or reject closing rawtext tags (such as </textarea>) when they appeared within attribute values. This allowed crafted payloads to survive sanitization and later escape their intended rendering context.
Technical Impact
An attacker who can supply input that is sanitized by the vulnerable DOMPurify version and then rendered inside a rawtext element (textarea, title, script, style) can execute arbitrary JavaScript in the victim's browser. This enables session hijacking, credential theft, DOM manipulation, and unauthorized actions performed as the victim user.
Severity Justification
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N scores 6.1 (Medium). Exploitability is conditional: the vulnerable code path is only triggered when sanitized output is placed inside rawtext elements, which is not the default usage pattern. User interaction is required. VulnCheck's CVSS v4 assessment scores this at 5.1.
Affected Components
DOMPurify 3.1.3 – 3.2.6DOMPurify 2.5.3 – 2.5.8 (no patch available for 2.x branch)
Remediation Steps
- Upgrade DOMPurify to version 3.2.7 or later: `npm install dompurify@latest` or `yarn upgrade dompurify`.
- If you are on the 2.x branch (2.5.3–2.5.8), migrate to 3.x — the 2.x branch will not receive a patch for this CVE.
- Audit your codebase for any pattern where DOMPurify output is inserted into rawtext elements (textarea, title, script, style). Apply additional HTML entity encoding at those insertion points as a defence-in-depth measure.
- Add or strengthen a Content Security Policy (CSP) header to limit the impact of any future XSS bypass. Start in report-only mode to avoid breaking changes.
- Verify the installed version after upgrading (see verification steps).
Verification Steps
- Run `npm list dompurify` or `yarn list --pattern dompurify` and confirm the installed version is 3.2.7 or higher.
- Search your codebase for patterns like `textarea.innerHTML = DOMPurify.sanitize(...)` or equivalent — these are the vulnerable injection points.
- Use the GitHub Security Advisory GHSA-v8jm-5vwx-cfxm as a reference payload to test your sanitization pipeline in a staging environment.
- Check your CSP violation reports (if configured) for any unexpected script-src violations after deployment.
Code Examples (javascript)
// Vulnerable: sanitized output placed directly inside a textarea element
const clean = DOMPurify.sanitize(userInput); // DOMPurify 3.1.3–3.2.6
textareaElement.innerHTML = clean; // payload escapes rawtext context
// Fixed: upgrade to 3.2.7+
// npm install dompurify@3.2.7
const clean = DOMPurify.sanitize(userInput); // 3.2.7 correctly handles rawtext closing tags
textareaElement.value = clean; // Prefer .value over .innerHTML for textarea elements
Best Practices
- Prefer setting textarea content via `.value` rather than `.innerHTML` — this avoids HTML parsing entirely and eliminates this class of vulnerability.
- Avoid placing DOMPurify-sanitized output inside rawtext elements (textarea, title, script, style) using innerHTML; use the appropriate DOM property instead.
- Pin your DOMPurify version in package.json and run automated dependency audits (e.g., `npm audit`) in CI to catch future CVEs early.
- Implement a Content Security Policy with a strict script-src directive as a defence-in-depth layer against XSS bypasses.
Found this in your infrastructure?
VulWall scans for this and dozens of other issues automatically.
Scan Your Domain Free