Part 49: React Security Best Practices: XSS, CSRF & Token Storage
Security is paramount in web applications. While React includes several built-in protections, understanding potential vulnerabilities is crucial.
1. Cross-Site Scripting (XSS) Prevention
React automatically escapes all string expressions embedded inside {} before rendering them into the DOM:
const userComment = '<script>alert("Hacked!")</script>';
// React renders this safely as harmless plain text, NOT executable script:
return <div>{userComment}</div>;
⚠️ The Danger: dangerouslySetInnerHTML
If you must render rich HTML (such as markdown-rendered HTML or CMS content), always sanitize it with DOMPurify:
import DOMPurify from 'dompurify';
export default function SafeHtmlViewer({ untrustedHtml }) {
const cleanHtml = DOMPurify.sanitize(untrustedHtml);
return (
<div dangerouslySetInnerHTML={{ __html: cleanHtml }} />
);
}
2. Preventing Malicious javascript: Links
// ❌ DANGEROUS: If user supplies 'javascript:stealData()' as url
<a href={userSubmittedUrl}>Visit Website</a>
// VALIDATE URL PROTOCOL
function isSafeUrl(url) {
try {
const parsed = new URL(url);
return ['http:', 'https:'].includes(parsed.protocol);
} catch {
return false;
}
}
3. JWT Token Storage: localStorage vs. httpOnly Cookies
| Storage Location | XSS Vulnerability | CSRF Vulnerability | Recommendation |
|---|---|---|---|
localStorage |
Accessible to any rogue JS script | Immune | Risky for sensitive auth tokens |
httpOnly Cookie |
Inaccessible to JavaScript | Vulnerable without SameSite | Preferred for production |
Key Takeaways
- React automatically escapes JSX string expressions to prevent XSS.
- Always sanitize markup with DOMPurify before using
dangerouslySetInnerHTML. - Store sensitive authentication tokens in
httpOnly,Secure,SameSite=Lax/Strictcookies.
In Part 50, we explore Production Build Optimization, CI/CD & Deployment!

