XSS in React: Understanding Vulnerable Functions and Security Risks
Although React is designed with security in mind, it does not eliminate XSS (Cross-Site Scripting) vulnerabilities entirely. Developers can still introduce security issues if they improperly handle user input. Below are the most common vulnerable functions and patterns in React that can lead to XSS.
🚨 Vulnerable Functions in React That Can Lead to XSS
1. dangerouslySetInnerHTML
React escapes all content by default, preventing XSS. However, using
dangerouslySetInnerHTML
disables this protection.If the inserted HTML is user-controlled and unescaped, XSS is possible.
🔴 Vulnerable Code Example
const userComment = "<img src=x onerror=alert(1)>"; // Unsanitized user input
const CommentComponent = () => {
return <div dangerouslySetInnerHTML={{ __html: userComment }} />;
};
✅ Fix: Use a proper HTML sanitizer like DOMPurify before inserting HTML.
import DOMPurify from "dompurify";
const safeComment = DOMPurify.sanitize(userComment);
const SafeComponent = () => {
return <div dangerouslySetInnerHTML={{ __html: safeComment }} />;
};
2. ref.innerHTML
Manipulation
- Directly setting
innerHTML
on a DOM element retrieved viaref
bypasses React’s escaping mechanisms.
🔴 Vulnerable Code Example
import { useRef, useEffect } from "react";
const UnsafeComponent = ({ userInput }) => {
const divRef = useRef(null);
useEffect(() => {
divRef.current.innerHTML = userInput; // XSS possible if userInput is malicious
}, [userInput]);
return <div ref={divRef}></div>;
};
✅ Fix: Use textContent
instead to avoid HTML parsing.
useEffect(() => {
divRef.current.textContent = userInput; // Safe alternative
}, [userInput]);
3. eval()
or new Function()
in JSX or Event Handlers
- Using
eval()
ornew Function()
on user input creates a JavaScript execution vulnerability.
🔴 Vulnerable Code Example
const executeUserCode = (code) => {
eval(code); // 🚨 User-controlled input can execute arbitrary JS
};
executeUserCode("alert(document.cookie)");
✅ Fix: Never use eval()
. Instead, use strict function validation and controlled execution environments.
4. window.location
or document.write()
with User Input
- Appending user input to
window.location
ordocument.write()
without validation can allow malicious script injection.
🔴 Vulnerable Code Example
const userQuery = new URLSearchParams(window.location.search).get("q");
document.write(`<h1>${userQuery}</h1>`); // XSS if q=<script>alert(1)</script>
✅ Fix: Encode user input before using it in the DOM.
const safeQuery = DOMPurify.sanitize(userQuery);
document.write(`<h1>${safeQuery}</h1>`);
5. Inline Event Handlers (onClick
, onMouseOver
, etc.)
- React normally prevents XSS in JSX attributes, but passing unsanitized user input as an event handler function can be dangerous.
🔴 Vulnerable Code Example
const UserAction = ({ userScript }) => {
return <button onClick={() => eval(userScript)}>Run</button>; // 🚨 Dangerous!
};
✅ Fix: Only allow pre-defined functions.
const UserAction = () => {
const handleClick = () => alert("Safe execution");
return <button onClick={handleClick}>Run</button>;
};
🛡️ Best Practices to Prevent XSS in React
✅ 1. Never Use dangerouslySetInnerHTML
(Unless Necessary)
- If you must use it, sanitize the input with DOMPurify or another HTML sanitizer.
✅ 2. Always Escape User Input
- If displaying user content, ensure it is encoded properly before inserting it into the DOM.
✅ 3. Avoid Using eval()
and new Function()
- These functions should never be used in React applications.
✅ 4. Be Careful with refs
and innerHTML
- Direct DOM manipulation bypasses React’s security protections.
✅ 5. Use Security Headers to Prevent Injection
- Set Content Security Policy (CSP) headers to mitigate the risk of inline scripts being executed.
✅ 6. Use Trusted Libraries for Input Sanitization
- DOMPurify,
xss-filters
, or other sanitization libraries should be used to clean user input.
🛑 Key Takeaways
React’s default escaping helps prevent XSS, but bad coding practices can still introduce vulnerabilities.
Avoid
dangerouslySetInnerHTML
unless you sanitize input with a trusted library like DOMPurify.Never use
eval()
,new Function()
, or directly setinnerHTML
in refs.Sanitize all user input before rendering or processing it.
By following these security principles, you can keep your React applications safe from XSS attacks. 🚀