Building secure React applications requires more than just following best practices—it demands understanding the specific vulnerabilities that single-page applications face and implementing defensive patterns from the start.
1. Prevent Cross-Site Scripting (XSS)
By default, React escapes values in JSX. But shortcuts like dangerouslySetInnerHTML
open the door to attackers:
// Vulnerable
<div dangerouslySetInnerHTML={{__html: user.bio}} />
Instead, sanitize with a trusted library:
import DOMPurify from 'dompurify';
const safeBio = DOMPurify.sanitize(user.bio);
<div dangerouslySetInnerHTML={{__html: safeBio}} />
2. Treat Authentication as Sacred
Tokens in localStorage
are exposed to XSS. A safer pattern is httpOnly cookies with CSRF tokens:
await fetch('/api/login', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': await getCSRFToken()
},
body: JSON.stringify(credentials)
});
3. Sanitize Props and Inputs
Props aren’t immune. Always validate and sanitize before rendering:
const cleanQuery = query.replace(/[<>]/g, '');
<h2>Results for: {cleanQuery}</h2>
4. Keep State Lean
Context and Redux should not carry secrets. Expose only what the UI truly needs (permissions, IDs, roles).
5. Respect Environment Configurations
Anything prefixed with REACT_APP_
is visible to the client. Keep true secrets server-side, delivered through a secure API.
6. Secure Headers at Deployment
Defend React apps at the edge by setting strict headers:
res.setHeader('Strict-Transport-Security', 'max-age=31536000');
res.setHeader('Content-Security-Policy',
"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"
);
Security isn’t a feature; it’s a foundation.
When baked into your React components and architecture, these patterns create user trust that lasts.
Thanks for reading! If this post was insightful for you, please share it with your team or leave a comment with your own security wins.
Looking for a partner who builds React apps with security at the core?
See how I help teams deliver resilient frontends: kodex.studio
Top comments (2)
Great breakdown of React security essentials !! I especially appreciate the emphasis on avoiding 'dangerouslySetInnerHTML' it's a common pitfall for developers new to React. One additional layer I’ve found useful is implementing a Content Security Policy (CSP) that includes a nonce for inline scripts. It’s a bit more work but can significantly reduce XSS risks.
Curious how do you approach balancing security with performance, especially when sanitizing large amounts of user-generated content?
Absolutely spot on!
I’ve faced similar challenges, especially with XSS vulnerabilities when rendering user-generated content. Using DOMPurify saved me from a lot of headaches.
Another thing I’ve found useful is keeping state minimal , never store sensitive info in Redux or Context; just the info needed for the UI. It’s crazy how many people overlook that in SPAs.
how do you handle refresh tokens securely in client-heavy React apps? Do you lean fully on httpOnly cookies or a hybrid approach?