01.Trusting Frontend Validation
Frontend validation is UX. Backend validation is security. Any data coming from the client can be manipulated with Postman, curl, or browser devtools. Always re-validate every input server-side using a schema validation library like Zod or class-validator. Never assume the client sent what the form asked for.
02.CORS Wildcards in Production
Setting Access-Control-Allow-Origin: * in production means any website can make authenticated requests to your API on behalf of your users. Whitelist only the specific origins you need. In NestJS, configure the CORS whitelist explicitly using the app.enableCors() allowedOrigins array.
03.Missing Rate Limiting
Without rate limiting, your API is vulnerable to brute-force attacks on login endpoints, credential stuffing, scraping, and DoS amplification. At minimum, rate-limit login attempts (5/min per IP), password resets (3/hour per email), and all public endpoints. Use Redis-backed sliding window counters for accuracy.
- ▸Login: 5 attempts per minute per IP
- ▸Password reset: 3 per hour per email
- ▸Public API: 100 requests per minute per IP
- ▸Authenticated API: 1000 requests per minute per user
04.Exposing Stack Traces in Error Responses
Never send raw error stack traces to the client in production. They reveal file paths, library versions, database schemas, and internal logic that attackers can use to craft targeted exploits. Use a global exception filter that logs the full error server-side but returns only a generic error message to the client.
05.Open S3 Buckets
S3 buckets are private by default — but misconfigured IAM policies, bucket ACLs, or CDK mistakes can expose them publicly. Enable S3 Block Public Access at the account level. Run AWS Config rules to detect public buckets. Never store sensitive data in buckets without server-side encryption (SSE-S3 or SSE-KMS).
06.Not Rotating Secrets
Hardcoded credentials in environment variables that never rotate are ticking time bombs. Use AWS Secrets Manager with automatic rotation for database credentials, API keys, and JWT secrets. Reference secrets by ARN in your Lambda and ECS configurations — never embed them in code or commit them to git.