flawopen.com/XSS in JavaScript/dangerouslySetInnerHTML
Is React's dangerouslySetInnerHTML safe?
Think of ordinary JSX as a label printer: text stays text. dangerouslySetInnerHTML switches to a markup press that interprets the supplied string as HTML. If that string contains attacker-controlled content, the browser may treat it as active markup. Use this sink only for HTML you have deliberately trusted or sanitized for the exact HTML context.
Why normal JSX doesn't need this
function Comment({ html }) {
return <p dangerouslySetInnerHTML=
{{ __html: html }} />;
}
function Comment({ text }) {
return <p>{text}</p>;
}
When is dangerouslySetInnerHTML appropriate?
Use it only when the product must preserve a restricted rich-text format that cannot be represented as ordinary React children. A CMS, editor, or Markdown renderer is not automatically trusted: stored content and renderer output can still contain untrusted markup. Define the allowed elements and attributes for the feature, sanitize with a maintained HTML sanitizer such as DOMPurify, and pass the sanitized result directly to this sink.
Doing it correctly
Sanitize immediately before assigning the value to dangerouslySetInnerHTML, using a maintained library such as DOMPurify. Do not use regular expressions as an HTML sanitizer. Avoid modifying the sanitized string afterward; a later transformation can invalidate the sanitizer's guarantees. Keep the sanitizer and its parsing environment patched.
A deny-list of familiar tags is incomplete because risk can come from attributes, URL-bearing fields, namespaces, and parser behavior. Choose a small allow-list of the elements and attributes the feature needs, then configure the sanitizer for that policy. Review links and other URL-bearing attributes separately against the destinations your product permits.
How to check your codebase
grep -rn "dangerouslySetInnerHTML" --include="*.jsx" --include="*.tsx" .FAQ
It depends on the renderer and its configuration. Check whether raw HTML is accepted and whether the renderer sanitizes its output; do not assume Markdown conversion alone makes HTML safe.
Yes — same mechanism, same rule: sanitize untrusted content immediately before it reaches v-html, never trust it by default.
References
- React docs — dangerouslySetInnerHTML
- DOMPurify — HTML sanitizer and usage notes
- MDN — Element.innerHTML security considerations
- flawopen.com — XSS in JavaScript