dangerouslySetInnerHTML Without Sanitization
Using React's dangerouslySetInnerHTML with unsanitized user input allows attackers to inject malicious scripts that execute in other users' browsers.
How It Works
React escapes content by default, preventing XSS. However, dangerouslySetInnerHTML bypasses this protection and renders raw HTML. When the HTML comes from user input (comments, profile bios, rich text editors), attackers inject script tags, event handlers (onerror, onload), or JavaScript URIs that execute in other users' browsers. This enables session hijacking, credential theft, and account takeover. The attack persists because the malicious HTML is stored in the database and rendered for every visitor.
function Comment({ comment }) {
return (
<div
dangerouslySetInnerHTML={{ __html: comment.body }}
/>
);
}import DOMPurify from 'dompurify';
function Comment({ comment }) {
const sanitized = DOMPurify.sanitize(comment.body, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br'],
ALLOWED_ATTR: ['href']
});
return (
<div dangerouslySetInnerHTML={{ __html: sanitized }} />
);
}Real-World Example
In 2020, a Stored XSS vulnerability in Webflow's CMS allowed attackers to inject JavaScript through rich text fields. The malicious code executed for every visitor viewing the affected page, potentially compromising thousands of users.
How to Prevent It
- Always sanitize HTML with DOMPurify before using dangerouslySetInnerHTML
- Restrict allowed tags and attributes to the minimum necessary
- Prefer rendering Markdown with a safe parser instead of raw HTML
- Use Content Security Policy headers to mitigate XSS impact
Affected Technologies
Data Hogo detects this vulnerability automatically.
Scan Your Repo FreeRelated Vulnerabilities
Authentication Tokens in localStorage
highStoring JWT tokens, session tokens, or API keys in localStorage makes them accessible to any JavaScript running on the page, including XSS payloads.
__NEXT_DATA__ Secrets Exposure
highNext.js page props passed through getServerSideProps or getStaticProps leak sensitive data like API keys, database URLs, or internal configuration via the __NEXT_DATA__ script tag.
Source Maps Exposed in Production
mediumJavaScript source map files (.map) are publicly accessible in production, revealing the complete original source code including comments, variable names, and internal logic.
Open CORS in Next.js API Routes
mediumNext.js API routes configured with Access-Control-Allow-Origin: * allow any website to make authenticated cross-origin requests, enabling CSRF-like attacks.