Secure Coding Practices for Frontend Engineers
Modern frontend engineers build applications that are richer and more complex than ever. With React, TypeScript, and Node.js powering SPAs and APIs, the frontend is an active part of the security perimeter. This article maps practical secure coding practices for frontend engineers to the OWASP Top 10 (2021), giving you a clear checklist for building safer apps.
1 — Broken Access Control
Why it matters: Relying only on client-side UI restrictions is insufficient — attackers may call backend endpoints directly.
Practices: Enforce access control server-side in Node.js, use frontend route guards for UX only, and avoid shipping privileged data in the bundle.
// React route guard (UX only — backend must enforce)
<Route path="/admin" element={user?.role === 'admin' ? <AdminPanel /> : <Navigate to="/403" />} />
2 — Cryptographic Failures
Why it matters: Mishandled tokens and secrets lead to data exposure.
Practices: Use HTTPS & HSTS, store session tokens in HttpOnly Secure cookies, and never hardcode secrets in frontend code.
// Good: expose only public keys to frontend
const STRIPE_PUBLIC_KEY = import.meta.env.VITE_STRIPE_PUBLIC_KEY;
3 — Injection
Why it matters: XSS and other injection flaws let attackers run arbitrary code in a user's browser.
Practices: Sanitize untrusted HTML (DOMPurify), validate inputs both client & server (TypeScript + Zod), and avoid inserting raw HTML.
import DOMPurify from 'dompurify';
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }} />
4 — Insecure Design
Why it matters: Security needs to be part of the architecture, not an afterthought.
Practices: Threat model your application flows, apply least privilege, and design robust session & logout behavior.
5 — Security Misconfiguration
Why it matters: Misconfigured headers, CORS, or debug settings open easy attack surfaces.
Practices: Use Helmet for headers, configure a strict CSP, avoid wildcard CORS, and remove debug instrumentation in production.
import helmet from 'helmet';
app.use(helmet());
6 — Vulnerable and Outdated Components
Why it matters: A vulnerable npm dependency can compromise your whole app.
Practices: Run npm audit
, use Dependabot/Renovate, prefer maintained libraries and pin versions with lockfiles.
7 — Identification & Authentication Failures
Why it matters: Weak session management and exposed tokens enable account takeover.
Practices: Use secure cookies, handle token expiry gracefully, never leak tokens in logs or URLs, and implement refresh & revocation.
8 — Software & Data Integrity Failures
Why it matters: Supply chain attacks and tampered assets break trust in your frontend.
Practices: Use Subresource Integrity (SRI) for third-party scripts, prefer trusted CDNs or self-host, and harden CI/CD pipelines.
<script src="https://cdn.example.com/lib.js"
integrity="sha384-abc123..."
crossorigin="anonymous"></script>
9 — Security Logging & Monitoring Failures
Why it matters: Lack of monitoring means incidents go undetected.
Practices: Use frontend error monitoring (Sentry), log critical auth events server-side, avoid logging secrets, and configure alerts for suspicious activity.
10 — Server-Side Request Forgery (SSRF)
Why it matters: While SSRF is mainly a backend concern, the frontend can accidentally expose dangerous capabilities (e.g., letting users supply URLs to backend proxies).
Practices: Never let the frontend send arbitrary internal URLs to the backend — use server-side allowlists and validate inputs.
Comments