CVE-2026-47423 - DOMPurify selectedcontent re-clone XSS
DOMPurify 3.4.4 allows selectedcontent by default. In affected browsers,
that creates a re-clone sequence where attacker-controlled markup can become
unsafe again after DOMPurify has already walked the subtree. Applications that
sanitize untrusted HTML with the string-input path and then inject the returned
string into the page can still end up executing script.
This matters anywhere a product treats DOMPurify as the trust boundary for rich text: comments, knowledge bases, support messages, markdown previews, agent output rendering, CMS blocks, email templates, or admin content viewers. The patch is small, but the review should also verify that sanitized output is not being fed back into unsafe sinks or transformed again afterward.
When to use it
Use this recipe when a web application depends on DOMPurify as the trust boundary for rich text, markdown output, CMS content, support messages, email previews, model-generated HTML, or other attacker-controlled markup. It is designed for source-code remediation, sanitizer-to-sink review, frontend regression testing, and evidence that sanitized content remains inert after the application’s real render path.
Inputs
- DOMPurify version, package manager and lockfile state, rich-text rendering surfaces, sanitizer wrapper code, Trusted Types policy, and deployment bundle inventory.
- Source paths that call
DOMPurify.sanitize, useinnerHTMLordangerouslySetInnerHTML, transform markdown/HTML, render previews, or show privileged review/admin content. - Regression fixtures for benign rich text, selectedcontent-like markup, post-sanitization transforms, framework sink wrappers, and rejected executable behavior.
- Boundary evidence: who can author HTML, who views it, tenant/admin crossing, CSP posture, generated bundles, SBOMs, dependency reports, and rollout owner.
Affected versions
| Package | Vulnerable versions | Fixed versions |
|---|---|---|
dompurify |
3.4.4 |
3.4.5+ |
Indicator-of-exposure
- The repository resolves
dompurify 3.4.4. - Attacker-controlled or mixed-trust HTML is sanitized by DOMPurify and then
inserted into the DOM using
innerHTML,dangerouslySetInnerHTML, template rendering, or equivalent string-to-DOM sinks. - The app supports rich text, imported HTML, markdown-to-HTML pipelines, WYSIWYG editors, email or support rendering, documentation rendering, or model-generated HTML.
- Sanitized content can be viewed by privileged users whose sessions, tokens, or cross-tenant data matter.
Quick checks:
rg -n "dompurify|DOMPurify|sanitize\\(|dangerouslySetInnerHTML|innerHTML|selectedcontent|trustedTypes|createHTML|markdown|rich text|WYSIWYG" .
npm ls dompurify
pnpm why dompurify
yarn why dompurify
Windows:
rg -n "dompurify|DOMPurify|sanitize\(|dangerouslySetInnerHTML|innerHTML|selectedcontent|trustedTypes|createHTML|markdown|rich text|WYSIWYG" .
npm ls dompurify
pnpm why dompurify
yarn why dompurify
Remediation strategy
- Upgrade
dompurifyto3.4.5+. - Regenerate lockfiles, SBOMs, bundles, and dependency reports.
- Add regression tests with inert attacker-controlled HTML fixtures that assert sanitized output stays inert after the app’s full render path, not only after the first sanitize call.
- Review HTML sinks and post-sanitization transforms. Avoid taking a sanitized string and then mutating or reinterpreting it in ways that bypass the sanitizer boundary.
- If the upgrade cannot deploy immediately, disable high-risk rich-text rendering paths or render sanitized content as text in the highest-trust views.
The prompt
Model context: this prompt was generated by GPT 5.5 Extra High reasoning.
You are remediating CVE-2026-47423 / GHSA-87xg-pxx2-7hvx, a DOMPurify
sanitization bypass through `selectedcontent` re-cloning. Produce exactly one
output:
- A reviewer-ready PR/change request that upgrades DOMPurify, verifies safe
rendering of attacker-controlled HTML, adds regression fixtures, refreshes
generated artifacts, and documents operator actions, or
- TRIAGE.md if this repository does not control an affected DOMPurify-based
rich-text rendering path.
## Rules
- Scope only CVE-2026-47423 / GHSA-87xg-pxx2-7hvx and directly related
sanitizer-to-sink rendering paths.
- Do not execute live XSS payloads in a browser session with real cookies,
tokens, customer data, or privileged accounts.
- Treat sessions, JWTs, CSRF tokens, tenant data, support content, and model
output as sensitive.
- Do not remove sanitization entirely to get tests passing.
- Do not auto-merge.
## Steps
1. Inventory every `dompurify` dependency, lockfile, bundle, workspace, image,
SBOM, and generated dependency report controlled by this repository.
2. Determine whether `dompurify 3.4.4` is resolved and where it sanitizes
attacker-controlled or mixed-trust HTML.
3. Trace the full rendering path after sanitization: template rendering,
markdown transforms, React/Vue wrappers, `innerHTML`,
`dangerouslySetInnerHTML`, Trusted Types policies, or editor preview code.
4. If the repository does not control an affected rich-text rendering path,
stop with `TRIAGE.md` listing checked files and resolved versions.
5. Upgrade `dompurify` to `3.4.5+` and refresh lockfiles, generated dependency
output, bundles, images, and SBOMs.
6. Add safe regression fixtures that prove attacker-controlled HTML remains
inert after the application's real sanitize-and-render path:
- sanitize input using repository code paths;
- assert the rendered result omits executable behavior;
- cover `innerHTML` or framework sink wrappers used here;
- avoid live payload execution and real-session browsers.
7. Review and fix adjacent sink issues:
- avoid post-sanitization DOM mutation that can reintroduce unsafe nodes;
- avoid serializing and reparsing sanitized HTML in a less-constrained path;
- prefer explicit allow-lists for supported rich-text features.
8. Add a PR body section named `CVE-2026-47423 operator actions` that states:
- DOMPurify versions before and after;
- which user-controlled HTML surfaces were reviewed;
- which sink wrappers or rendering helpers were tested;
- whether privileged viewers or tenant-crossing surfaces existed;
- whether temporary rendering restrictions remain until full rollout.
9. Run available validation: package install, unit tests, sanitizer fixtures,
frontend tests, build, lint/typecheck, dependency/security scans, and SBOM
refresh.
10. Use PR title:
`fix(sec): remediate CVE-2026-47423 in DOMPurify usage`.
## Stop conditions
- No affected `dompurify 3.4.4` resolution exists in a controlled rich-text
surface.
- The repository only references DOMPurify in docs, examples, or non-executed
code.
- Meaningful verification would require live XSS execution in a privileged
environment.
- Validation fails for unrelated pre-existing reasons; document those failures
instead of broadening scope.
Output contract
- A reviewer-ready PR or change request that upgrades DOMPurify, refreshes dependency artifacts, verifies the real sanitize-to-render path, and documents rich-text surface review.
- Or a
TRIAGE.mdfile that lists inspected package files, rendered bundles, sanitizer wrappers, rich-text surfaces, owner, observed version, required fix, and residual risk. - The output must include exact validation commands and must not execute live XSS payloads with real sessions, expose customer-authored content, or remove sanitization to make tests pass.
Verification - what the reviewer looks for
- No controlled lockfile or bundle resolves
dompurify 3.4.4. - Tests cover the real sanitize-to-render path, not only a direct call to
DOMPurify.sanitize. - High-trust viewer surfaces and string-to-DOM sinks were explicitly reviewed.
- Generated artifacts and dependency reports reflect the fixed version.
Watch for
- Updating
package.jsonwhile a workspace lockfile or vendor bundle still ships3.4.4. - Sanitizing correctly but later feeding the result into a second unsafe HTML transform.
- Fixing public comment views while admin-only review panes still use stale DOMPurify builds.
- Tests that assert only string equality without exercising the app’s actual rendering helper.
Related recipes
- Source code injection sink audit
- Source code secrets and data exposure audit
- OWASP Top 10 2026 audit
- SAST finding triage and fix