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.
Ready to Identify & Fix Vulnerabilities in Your Platform?
Schedule a confidential 20-minute scoping review with our lead security architects under mutual NDA. We evaluate your APIs, business logic, and enterprise readiness.