Key vulnerabilities include XSS (mitigated by React's auto-escaping, but watch dangerouslySetInnerHTML and URL injection), CSRF (use tokens in API requests, SameSite cookies), and insecure storage (avoid localStorage for sensitive data, prefer httpOnly cookies).
XSS (Cross-Site Scripting):
React's Built-in Protection:
{} by default<div>{userInput}</div> is safeXSS Vectors to Watch:
dangerouslySetInnerHTML - bypasses escaping, sanitize with DOMPurifyjavascript: URLs in href/src - NOT escaped, validate URLsCSRF (Cross-Site Request Forgery):
SameSite=Strict or SameSite=Lax cookiesAuthentication & Storage:
Additional Security Measures:
npm audit for vulnerable dependencies// SAFE: React auto-escapes by default
function Comment({ text }) {
return <p>{text}</p>; // <script> becomes <script>
}
// DANGEROUS: dangerouslySetInnerHTML bypasses escaping
function UnsafeHTML({ html }) {
return <div dangerouslySetInnerHTML={{ __html: html }} />;
}
// SAFE: Sanitize with DOMPurify before using
import DOMPurify from 'dompurify';
function SafeHTML({ html }) {
const sanitized = DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p'],
ALLOWED_ATTR: ['href', 'target']
});
return <div dangerouslySetInnerHTML={{ __html: sanitized }} />;
}
// DANGEROUS: javascript: URL injection
function UnsafeLink({ href, children }) {
// User could pass: javascript:alert('XSS')
return <a href={href}>{children}</a>;
}
// SAFE: Validate URL protocol
function SafeLink({ href, children }) {
const isValidUrl = (url) => {
try {
const parsed = new URL(url, window.location.origin);
return ['http:', 'https:', 'mailto:'].includes(parsed.protocol);
} catch {
return false;
}
};
if (!isValidUrl(href)) {
return <span>{children}</span>; // Render as text
}
return <a href={href}>{children}</a>;
}