Join our Newsletter — 33% off our NHI Course
Home› FAQ› Cyber Security› How should security teams prevent DOM-based XSS in…
Cyber Security

How should security teams prevent DOM-based XSS in React applications that render user-controlled content?

← Back to all FAQ
By NHI Mgmt Group Editorial Team Updated October 30, 2026 Domain: Cyber Security

Use React’s default escaping for ordinary text rendering, and only render HTML when there is a clear business need. If HTML must be inserted, sanitize it first and keep raw user input out of DOM mutation paths such as innerHTML. Treat refs, rich text, and dynamic markup as untrusted boundaries, and validate them with testing in development and CI.

Why React’s default escaping is the first line of defence

React’s ordinary text rendering is safe because it escapes content before it reaches the DOM. That means the main job for security teams is not “adding more filters everywhere”, but preserving the safe default and resisting the urge to bypass it. Once a code path starts treating user input as markup, the browser stops seeing plain data and starts seeing executable structure.

That distinction matters most in component trees that mix user content with rich formatting, previews, comments, CMS output or support tickets. The safest pattern is to keep user-controlled content as text for as long as possible, and to treat any conversion into HTML as an exceptional, reviewed decision rather than a normal rendering shortcut.

For teams building or reviewing React interfaces, a practical reference point is the React and Next.js Security Guide, which covers the framework-level places where unsafe rendering choices usually enter the app.

Where DOM-based XSS enters the React rendering path

DOM-based XSS appears when trusted client-side code takes attacker-controlled data and writes it into a dangerous sink such as innerHTML, unsafe template rendering, or a ref-backed DOM mutation. In React, that often happens outside the normal JSX text path, which is why the problem is usually introduced by escape hatches, not by standard component rendering.

Common pressure points include rich text editors, markdown renderers, preview panes, CMS content, and components that directly manipulate nodes through refs. Security teams should pay close attention when a developer says the content is “already sanitised somewhere else”, because that assumption often breaks across component boundaries, feature flags, and later refactors.

For a deeper explanation of the sink-level problem, the Trusted Types and DOM XSS Prevention Guide is useful because it focuses on injection sinks, safe policy design, and how to reduce reliance on unsafe DOM writes.

How to make user-controlled HTML safer without normalising unsafe patterns

If the product genuinely needs to render HTML, sanitisation is necessary but not sufficient. Teams should sanitise at the point where HTML is created or accepted, keep the policy strict, and ensure the sanitiser is applied consistently for every source of user-controlled markup. The goal is to make unsafe HTML a deliberately transformed artifact, not a casually passed-through string.

Just as important, do not let raw input flow through multiple transformation layers before rendering. Markdown, WYSIWYG editors, diff viewers, and server-rendered snippets can all reintroduce unsafe constructs after an earlier filter has run. Security review should therefore look for the complete data path, not only the final rendering call.

When React apps need broader XSS hardening patterns, NHI Mgmt Group’s Cross-Site Scripting (XSS) Prevention Guide is the broader reference for output encoding, sanitisation, Trusted Types, and CSP hardening.

Risk and Threat Considerations

DOM-based XSS in React is especially dangerous because it often executes entirely in the browser, after server-side controls have already done their work. Attackers target these client-side sinks to steal session data, change page content, trigger actions on behalf of the user, or plant persistent malicious behaviour in rich content flows.

Failure mechanism: A trusted React component accepts user-controlled markup or text, then writes it into the DOM through an unsafe sink such as innerHTML, an unsafe ref mutation, or an over-permissive rich text renderer. If sanitisation is incomplete, bypassed, or applied too late, the browser interprets attacker input as executable HTML or script-bearing structure.

Impact: The resulting XSS can lead to account compromise, unauthorized actions, data theft, session abuse, and the spread of malicious content across otherwise trusted application views. In apps with collaborative content or shared previews, a single unsafe rendering path can become a high-blast-radius browser-side compromise.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP ASVS and NIST SP 800-53 Rev 5 set the governance and control requirements practitioners need to meet.

FrameworkControl / ReferenceRelevance
OWASP ASVSV1 — Encoding and SanitizationReact DOM XSS prevention depends on safe output handling and sanitization.
V15 — Secure Coding and ArchitectureUnsafe DOM sinks and escape hatches are architecture and coding issues in React apps.
Recommendation — Apply V1 to encode untrusted content and sanitise any HTML before rendering. Apply V15 to avoid unsafe DOM mutation paths and design rendering boundaries around trust.
NIST SP 800-53 Rev 5SI-10 — Information Input ValidationUser-controlled markup must be validated and constrained before it reaches rendering sinks.
SC-18 — Mobile CodeBrowser-side script execution from injected markup is a mobile-code style execution risk.
CM-7 — Least FunctionalityLimiting HTML-rendering features reduces the attack surface for DOM-based XSS.
Recommendation — Use SI-10 to validate and constrain untrusted input before it is processed or rendered. Use SC-18 to restrict script-bearing content and reduce unsafe client-side execution paths. Apply CM-7 to disable unnecessary rendering capabilities and keep only required features.

Practitioner Guidance

What to verify: Confirm that ordinary content paths stay on React’s default escaping and that any HTML-rendering component has an explicit business justification, a sanitisation step, and a named owner. Pay special attention to ref usage, markdown libraries, content previews, and any code path that can reach innerHTML or equivalent DOM mutation APIs.

Decision rule: If the content can be rendered as text, do that and stop there. If HTML is unavoidable, treat the source as untrusted, sanitise before rendering, and test the exact sink in development and CI so regressions are caught where they are introduced, not after release.

Practitioner takeaway: The safest React posture is to preserve text rendering by default and make every escape hatch observable, reviewable, and testable, because DOM-based XSS usually appears where teams stop treating user-controlled content as data.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Reviewed and updated by the NHIMG editorial team on October 30, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org