CVE-2026-65898
High · 7.2CVSS
7.2
EPSS
0.3%
Published
Jul 23, 2026
CISA due date
—
Cloudanix analysis
A website feature meant to clean unsafe user content can be tricked into letting harmful code stay behind and run when someone views that content.
- Exploitation
- Requires User Interaction
- Attacker needs
- Low Privilege
- Complexity
- Moderate
- Impact
- Data Tampering
- Component
- Library
- Class
- XSS
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
DOMPurify versions before 3.4.11 can mishandle sanitizer configuration state when setConfig() is used together with an uponSanitizeAttribute hook. Because the ALLOWED_ATTR allowlist is not properly cloned, a hook can mutate shared sanitizer state and cause dangerous attributes, such as JavaScript event-handler attributes, to remain allowed for later sanitization operations. The practical result is stored cross-site scripting: content that should have been stripped of executable attributes can be stored and later rendered in another user’s browser, executing attacker-controlled JavaScript in the context of the vulnerable application.
Why it matters to the business
Applications that rely on affected DOMPurify versions to safely render user-generated HTML may expose users and administrators to account takeover, data theft, session hijacking, fraudulent actions, or unauthorized changes made through the victim’s browser. The risk is higher for collaboration platforms, CMSs, support portals, forums, rich-text editors, messaging systems, and any product that stores and redisplays sanitized HTML. Although this issue is not currently listed in CISA KEV and has low EPSS at publication time, it affects a widely used client-side sanitization library, so vulnerable downstream applications may be numerous and difficult to inventory.
How an attack unfolds
An attacker first needs a way to influence sanitizer configuration or register a DOMPurify hook, such as through a privileged content customization feature, plugin mechanism, compromised maintainer path, or application functionality that exposes hook behavior. The attacker registers an uponSanitizeAttribute hook that conditionally mutates the allowed-attribute list, for example by allowing an event-handler attribute such as onerror in a trusted or controlled sanitization path. Because affected DOMPurify versions do not clone ALLOWED_ATTR correctly in this configuration, the mutation persists beyond the intended hook invocation. The attacker then submits otherwise untrusted HTML containing a dangerous attribute. When the polluted sanitizer configuration is reused, the dangerous attribute is not removed. The payload is stored by the application and later rendered to another user. When the victim views the stored content, the browser fires the event handler and executes attacker-controlled JavaScript within the application origin.
How to fix it
Upgrade DOMPurify to version 3.4.11 or later wherever it is used, including direct dependencies, bundled frontend assets, vendored copies, CDN-pinned versions, and transitive packages that embed DOMPurify. If immediate upgrade is not possible, avoid using setConfig() with mutable shared configuration and uponSanitizeAttribute hooks; create isolated sanitizer instances or immutable configuration objects where supported; remove custom hooks that alter ALLOWED_ATTR or allow event-handler attributes; and enforce a deny-by-default policy for attributes beginning with on, javascript: URLs, SVG/MathML execution primitives, and unsafe URI schemes. Add defense in depth with a restrictive Content Security Policy that disallows inline script execution, though CSP should not be treated as a substitute for upgrading. Review application code to ensure untrusted users cannot influence sanitizer configuration, hook registration, plugin code, or rich-text rendering templates.
How to confirm the fix worked
Confirm that every deployed application bundle and package lock resolves DOMPurify to 3.4.11 or later. Search source code and built assets for DOMPurify.setConfig(), uponSanitizeAttribute, addHook(), ALLOWED_ATTR, and custom attribute allowlist logic, then verify that no hook can mutate a shared allowlist or permit event-handler attributes for untrusted content. Re-run frontend builds and verify that generated JavaScript bundles no longer include affected DOMPurify versions. Test representative stored-content workflows by submitting HTML containing attributes such as onerror, onload, onclick, formaction, srcdoc, and javascript: URI values, and confirm they are removed or neutralized before storage and before rendering. Use browser developer tools or automated security tests to confirm no attacker-supplied event handlers remain in the rendered DOM.
Typical attack path
- Identify an application using DOMPurify before 3.4.11 for stored rich-text or HTML sanitization.
- Find a path that permits hook registration, sanitizer configuration influence, plugin execution, or compromise of code that calls DOMPurify.setConfig().
- Register or introduce an uponSanitizeAttribute hook that mutates ALLOWED_ATTR to permit a dangerous attribute such as onerror.
- Trigger the trusted or controlled sanitization path so the shared allowlist becomes polluted.
- Submit untrusted stored HTML containing an executable event-handler attribute or equivalent browser-executed payload.
- Wait for another user, moderator, or administrator to view the stored content.
- Execute JavaScript in the victim’s browser under the vulnerable application’s origin and use that access to steal tokens, perform actions, or pivot within the application.
How to detect it
To determine whether exploitation already occurred, examine source-control history, plugin/theme changes, deployment artifacts, and administrator activity for unexpected DOMPurify hook registration or sanitizer configuration changes. Review application logs and stored-content records for HTML that contains event-handler attributes or unsafe URI schemes that should normally be removed by DOMPurify. Focus on content created shortly before suspicious user sessions, administrator actions, account changes, token refreshes, or anomalous API calls. Browser-side evidence may be limited because XSS often executes only in the victim’s session, so correlate server logs for creation of suspicious rich-text content with subsequent privileged actions from the victim account, unusual user-agent/IP changes, unexpected CSRF-like state changes, or outbound requests to unfamiliar domains. For forensic review of built assets, search deployed JavaScript bundles for affected DOMPurify versions and for hooks that mutate ALLOWED_ATTR. If CSP reporting is enabled, review violation reports for blocked inline event handlers, blocked script execution, or attempted exfiltration to unknown endpoints.
- DOMPurify.setConfig(
- uponSanitizeAttribute
- DOMPurify.addHook('uponSanitizeAttribute'
- DOMPurify.addHook("uponSanitizeAttribute"
- ALLOWED_ATTR
- onerror=
- onload=
- onclick=
- onmouseover=
- onfocus=
- onanimationstart=
- javascript:
- <img
- <svg
- <iframe
- srcdoc=
- xlink:href=
- data:text/html
- script-src-attr
- blocked-uri
- violated-directive
What your security team should do
- Inventory all applications and frontend bundles that include DOMPurify, including vendored, CDN-hosted, and transitive copies.
- Prioritize upgrades to DOMPurify 3.4.11 or later in applications that store and render user-generated HTML, especially administrative portals and collaboration features.
- Search source repositories for sanitizer hooks and configuration mutations involving setConfig(), addHook(), uponSanitizeAttribute, and ALLOWED_ATTR.
- Temporarily disable or restrict rich-text HTML input, custom plugins, and sanitizer customization features if the affected library cannot be upgraded promptly.
- Deploy or tighten Content Security Policy to reduce the impact of any missed XSS path, especially by blocking inline scripts and limiting script-src to trusted origins.
- Hunt stored content for event-handler attributes and unsafe URI schemes that should not survive sanitization.
- Review recent code changes, plugin uploads, CMS theme changes, and administrator actions for suspicious modifications to DOMPurify configuration or hooks.
- Add regression tests that verify dangerous HTML attributes are stripped in every stored-content rendering path.
The record
DOMPurify before 3.4.11 fails to clone the ALLOWED_ATTR allowlist when setConfig() is used with an uponSanitizeAttribute hook, allowing the hook to permanently mutate the shared allowlist. Attackers can register a hook that conditionally allows dangerous attributes like onerror for trusted elements, then submit untrusted content that inherits the polluted allowlist and executes event handlers as stored XSS.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|
Related vulnerabilities
- CVE-2026-96379 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96382 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96368 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96361 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96362 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96360 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96357 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96358 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79