Back to Blog
X

Security by Design in React Frontends

In this article

The frontend is not “just UI” — it is the first layer exposed to users, bots, and attacks. In LGPD, sensitive data, and enterprise integration projects, security starts in JSX, not after deploy.

These practices come from compliance dashboards, telecom portals, and products with auth and scraping.


1. XSS: do not trust dynamic HTML

Use dangerouslySetInnerHTML only with strict sanitization (DOMPurify or equivalent). For user content, prefer structured rendering:

tsx
// ❌ high risk
<div dangerouslySetInnerHTML={{ __html: userBio }} />

// ✅ sanitized markdown or plain text
<ReactMarkdown>{sanitizedContent}</ReactMarkdown>

Also validate URLs in href and src — javascript: still appears in malicious payloads.


2. Tokens: memory vs. storage

Avoid localStorage for access tokens in SPAs exposed to XSS. Safer patterns:

  • HttpOnly cookies for refresh tokens (backend sets Secure and SameSite)
  • Short-lived access tokens in memory (state/context)
  • Rotation and revocation on the server

If the product requires localStorage, document the trade-off and pair it with strict CSP.


3. Validation in layers

The frontend validates for UX; the backend validates for security. Never reverse that order:

ts
const emailSchema = z.string().email().max(254)
const parsed = emailSchema.safeParse(input)
if (!parsed.success) {
  setFieldError('email', 'Invalid email')
  return
}

On LGPD forms, also validate consent, purpose, and optional fields — badly formatted personal data can become an incident.


4. Dependencies and attack surface

npm audit is not enough. Also review:

  • Dependencies with suspicious postinstall scripts
  • Third-party scripts via tag manager without CSP
  • VITE_* variables — all exposed on the client

Never put secrets in VITE_-prefixed variables.


5. Headers and policies at the edge

Even on static SPAs, configure on CDN or nginx:

  • Content-Security-Policy (start with report-only)
  • X-Frame-Options or frame-ancestors
  • Referrer-Policy: strict-origin-when-cross-origin
  • Restrictive Permissions-Policy

React does not protect against clickjacking — the edge does.


Conclusion

Frontend React security combines safe rendering, conscious token handling, layered validation, and edge policies.

Treat every input as potentially malicious, every token as temporary, and every dependency as a risk point. More secure products also pass audits with fewer surprises.

Glauber Ariel Magalhães

Written by Glauber Ariel Magalhães

Senior software engineer. I write about React, performance, accessibility, and security — with examples from real projects.

Comments

Sign in with your GitHub account to comment. Comments are public, stored as Discussions on the blog's comments repository.