Node.js APIs are powerful but exposed to the internet. This guide covers practical security for Express/Fastify-style APIs.
Beginner: HTTPS and Environment
HTTPS only – Terminate TLS at a reverse proxy (Nginx, Caddy) or use a load balancer. Never send secrets over HTTP.
Environment – Store secrets in env vars or a vault; never in code. Use `NODE_ENV=production` and avoid verbose errors in production.
Intermediate: Authentication and Input
Authentication – Use JWTs or session cookies. For JWTs: short-lived access tokens; optional refresh tokens; verify signature and `exp`. Decode and debug with our [JWT Decoder](/tools/jwt-decoder/).
Input validation – Validate and sanitize all request body, query, and params. Use a schema library (e.g. Zod, Joi) and reject invalid input with 400.
javascript
1const schema = z.object({
2 email: z.string().email(),
3 password: z.string().min(8).max(128)
4});
5const body = schema.parse(req.body);
SQL/NoSQL injection – Use parameterized queries or an ORM; avoid concatenating user input into queries. For MongoDB, avoid `$where` with user input.
Advanced: Rate Limiting and Headers
Rate limiting – Apply to login and sensitive endpoints (e.g. `express-rate-limit`). Per-IP or per-user; return 429 when exceeded.
CORS – Whitelist origins; don’t reflect `Origin` blindly. Use credentials only when needed.
Expert: OWASP and Hardening
OWASP Top 10 – Address broken access control (authz checks on every protected route), cryptographic failures (strong algorithms, no sensitive data in URLs), and insecure design (least privilege, fail secure).
Logging – Log auth failures and anomalies; never log passwords or tokens. Use structured logs for analysis.
Securing APIs is iterative: start with HTTPS and validation, then add auth, rate limiting, and headers. Use our [JSON Formatter](/tools/json-formatter/) to validate request/response payloads during development.