GitHub Advisoryadvisory · npm
GHSA-vxr8-fq34-vvx9 DOMPurify: Trusted Types policy survives `clearConfig()` and can poison later `RETURN_TRUSTED_TYPE` output
LOW
Official page ↗
- Aliases
- CVE-2026-65899
- Ecosystem
- npm
- Packages
- dompurify
- Severity
- Low
- CVSS vector
- CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
- Weaknesses
- CWE-693
- Reviewed
- 2026-06-15
Affected packages
• npm dompurify: < 3.4.9 → fixed in 3.4.9
Description
Impact
A DOMPurify instance that is reused across trust boundaries can stay bound to a previously supplied `TRUSTED_TYPES_POLICY` even after `clearConfig()` is called. A later caller that requests `RETURN_TRUSTED_TYPE` receives a `TrustedHTML` object created by the old policy, not by a clean default configuration.
If the old policy is unsafe or controlled by a less-trusted integration, this turns a later "default" sanitize call into script execution at a Trusted Types sink. `TRUSTED_TYPES_POLICY: null` on the later call also does not clear the retained policy.
dompurify-trusted-types-policy-survives-clearconfig-poc.js
Affected version
Tested against DOMPurify `3.4.8`, repository commit `825e617753ac1169306a542d3174a77f717a0cf6`.
Root cause
`_parseConfig()` overwrites `trustedTypesPolicy` when `cfg.TRUSTED_TYPES_POLICY` is truthy, but the default/null path only initializes the internal policy when `trustedTypesPolicy === undefined`. Once a custom policy has been set, later default config parsing leaves it in place.
Relevant code:
• `src/purify.ts:786-812` accepts and stores `cfg.TRUSTED_TYPES_POLICY`.
• `src/purify.ts:813-832` does not reset an existing policy when config has no policy or has `TRUSTED_TYPES_POLICY: null`.
• `src/purify.ts:2123-2125` signs the final serialized HTML with the retained policy when `RETURN_TRUSTED_TYPE` is true.
• `src/purify.ts:2133-2136` `clearConfig()` only clears `CONFIG` and `SET_CONFIG`; it does not reset `trustedTypesPolicy` or `emptyHTML`.
Local PoC
Run from the DOMPurify checkout, or set `DOMPURIFY_REPO`:
```bash
node /home/dompurify-trusted-types-policy-survives-clearconfig-poc.js
```
Observed output:
```json
{
"result": {
"baseline": "baseline",
"duringPolicy": "",
"afterClearString": "",
"afterClearTrustedType": "[object TrustedHTML]",
"afterClearTrusted": "",
"afterNullTrusted": "",
"mountedHTML": ""
},
"dialogs": [
"TT_POLICY_SURVIVED_CLEARCONFIG"
]
}
```
The important part is the split behavior after cleanup:
• `purify.clearConfig(); purify.sanitize(...);` returns a normal sanitized string (``), because the later call is not asking for a Trusted Type.
• `purify.clearConfig(); purify.sanitize(..., { RETURN_TRUSTED_TYPE: true });` still uses the old policy and returns attacker-controlled `TrustedHTML`.
• Passing `{ TRUSTED_TYPES_POLICY: null, RETURN_TRUSTED_TYPE: true }` also still returns attacker-controlled `TrustedHTML`.
Preconditions
This is a shared-instance state contamination issue. It matters when one DOMPurify instance is reused by multiple integrations, plugins, request handlers, or components with different trust levels, and a cleanup step relies on `clearConfig()` to restore safe defaults.
This is not a default string-input bypass. An attacker must be able to influence a prior `TRUSTED_TYPES_POLICY` on the reused instance, or a less-trusted integration must have installed an unsafe policy.
Severity
impact is XSS at a Trusted Types sink in applications that reuse a DOMPurify instance across trust boundaries. Attack complexity is high because exploitation depends on prior policy injection or a less-trusted integration and a later `RETURN_TRUSTED_TYPE` sink.
Suggested fix
Make `clearConfig()` reset Trusted Types state as part of restoring defaults, or have `_parseConfig()` explicitly clear `trustedTypesPolicy` and `emptyHTML` when `TRUSTED_TYPES_POLICY: null` is supplied.
Related
Alias · CVE (1)
- CVE-2026-65899 DOMPurify 3.0.0 before 3.4.9 does not reset the retained Trusted Types policy when clearConfig() is called, so a DOMPurify instance reused… vulnerability
Weakness · CWE (1)
- CWE-693 Protection Mechanism Failure weakness