Preventing XSS inside React & Next.js: Securing dangerouslySetInnerHTML
Securing dangerouslySetInnerHTML in React and Next.js
React escaping logic automatically neutralizes standard Cross-Site Scripting (XSS) vectors inside curly braces {userContent}. However, developers often bypass this default protection using dangerouslySetInnerHTML when rendering blog content or rich text emails.
The Cross-Site Scripting Risk
If you bind unvalidated inputs directly to dangerouslySetInnerHTML, an attacker can execute malicious scripts inside user browsers.
// VULNERABLE CODE
const unsafeHTML = `<img src="x" onerror="alert(document.cookie)" />`;
return <div dangerouslySetInnerHTML={{ __html: unsafeHTML }} />;
When this component mounts, the browser attempts to render the broken image, fires the onerror event, and executes the arbitrary script.
Safe Sanitization Standards
1. Use DOMPurify
Never render raw HTML without sanitizing it first. Install and use a battle-tested library like DOMPurify (for Node/Vite) or isomorphic-dompurify (for Next.js SSR):
import DOMPurify from "isomorphic-dompurify";
const CleanHTML = ({ unsafeHTML }) => {
const cleanHTML = DOMPurify.sanitize(unsafeHTML);
return <div dangerouslySetInnerHTML={{ __html: cleanHTML }} />;
};
2. Configure Content Security Policy (CSP) Headers
Implement strict Content Security Policy headers to disable inline scripts and enforce trusted domain origins.
Secure Your SaaS Assets Today
Ready to perform a deep-dive manual logical security audit? Schedule a scoping review with our lead architects.