Security Best Practices
Least privilege for service IAM, database users, and outbound HTTP - these rules harden Node.js APIs against OWASP-class failures.
How to Use This List
- Run before public API launch and annual penetration test prep.
- Pair with OWASP Top 10 for APIs as a mapping doc.
- Add CI grep for
process.envleaks,fetch(req.body.url), and missing auth on new routes. - Assign owners for dependency CVE triage and secret rotation.
A - Input and Authorization
- Validate bodies, query, params, and headers with Zod or JSON Schema.
unknownin, typed DTO out. - Check object-level authorization on every
:idroute.tenantIdandownerIdmatch the caller. - Return 404 for cross-tenant access, not 403. Avoid resource enumeration.
- Rate limit auth, OTP, and password reset endpoints.
express-rate-limitor gateway equivalent. - Never spread
req.bodyinto ORM create/update. Explicit allowlist fields only.
B - Secrets and Configuration
- Secrets from vault/SSM/k8s Secrets in production. Not
.envbaked into images. - Single
envmodule with Zod parse at boot. Ban scatteredprocess.envreads in app code. - Redact secrets in Pino serializers.
authorization, cookies, connection strings. - Rotate JWT signing keys and DB passwords without code deploy. Document runbook steps.
- Least-privilege DB user per service.
SELECT/INSERTon needed tables only, noSUPERUSER.
C - Network and SSRF
- Central
safeFetchfor user-supplied URLs. DNS resolve + block private IPs (SSRF Guards). - Disable redirect following on outbound user URLs. Re-validate each hop or reject 3xx.
- Egress allowlist at network layer for sensitive pods. Defense in depth beyond app code.
- Block cloud metadata IPs (
169.254.169.254). Common SSRF target on AWS/GCP. - mTLS or signed tokens for internal service calls. Not IP trust alone.
D - Headers, CORS, and Browser Clients
- Helmet on every browser-facing Express/Fastify app. Tune CSP with frontend team.
- CORS allowlist with credentials - never
*. Reflect exact allowed origins. - Handle OPTIONS before auth middleware. Preflight must not return 401.
- httpOnly cookies for browser sessions when possible. Reduce XSS token theft impact.
- Disable
x-powered-byand verbose error stacks in JSON 5xx responses.
E - Supply Chain and Operations
-
npm ci+npm audit --audit-level=highin CI. See Dependency Scanning. - Commit lockfile; review new dependencies in PR. Typosquat and postinstall scripts.
- Inventory routes in OpenAPI; deprecate unused endpoints. API9 hygiene.
- Run containers as non-root
USER node. Read-only root filesystem where possible. - Security review checklist in release template for breaking auth changes.
FAQs
What is the highest ROI item?
BOLA checks on every ID route. Authentication without object-level authorization is the most common API breach.
Is security only for public APIs?
Internal APIs still need auth, SSRF guards, and secret hygiene - lateral movement after one breach is common.
How often to rotate secrets?
API keys: quarterly or on employee offboarding. DB passwords: on schedule and after incidents. JWT keys: support kid rotation.
Do I need WAF and app security?
Yes - WAF filters obvious attacks; app enforces BOLA and business rules. Neither replaces the other.
NestJS-specific?
Global ValidationPipe with whitelist: true, guards on controllers, never skip auth on GraphQL resolvers.
How to enforce in CI?
Semgrep rules, npm audit, route inventory diff, and integration tests for BOLA cases.
What about rate limiting at CDN?
Good first layer. Still rate limit expensive app endpoints (login, search) at origin.
Security vs performance?
Validation and SSRF checks add microseconds. Body limits and rate limits protect both security and availability.
Related
- Security Basics - introductory examples
- OWASP Top 10 for APIs - risk mapping
- Security Rules - team coding standards
- Configuration Best Practices - secrets hygiene
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.