Security & Authentication

API Security Checklist: OWASP Top 10 for APIs

A practical API security checklist covering authentication, authorization, rate limiting, input validation, HTTPS, CORS, error handling, and logging.

Authentication (API Keys, OAuth, JWT)

Authentication verifies *who* is making the request.

  • [ ] Use HTTPS exclusively — never transmit credentials over HTTP
  • [ ] API Keys: treat as passwords — store hashed (SHA-256), never log raw keys, use 32+ bytes of entropy
  • [ ] JWT tokens: validate signature (alg, iss, aud, exp). Reject alg: none attacks explicitly
  • [ ] OAuth 2.0: use PKCE for public clients, short-lived access tokens (< 1 hour), refresh token rotation
  • [ ] Default credentials: remove all default/test credentials before production deployment
# JWT validation — always specify allowed algorithms
import jwt

payload = jwt.decode(
    token,
    key=PUBLIC_KEY,
    algorithms=['RS256'],   # never allow 'none'
    audience='api.example.com',
    issuer='auth.example.com',
)

Authorization

Authorization verifies *what* the authenticated identity may do.

  • [ ] Enforce authorization on every endpoint — never rely on the UI hiding buttons
  • [ ] Object-level authorization (IDOR): verify the authenticated user owns or has permission to access each object by ID
  • [ ] Function-level authorization: block lower-privilege users from calling admin endpoints
  • [ ] Principle of least privilege: scopes should grant only the minimum necessary access

IDOR (Insecure Direct Object Reference) is the #1 API vulnerability: an attacker changes GET /orders/42 to GET /orders/43 and gets someone else's order. Always filter by user_id = current_user.id.

Rate Limiting

  • [ ] Rate limit all endpoints, especially authentication and password reset
  • [ ] Limit by user ID as well as IP (authenticated users can change IPs)
  • [ ] Return 429 Too Many Requests with Retry-After header
  • [ ] Implement exponential backoff for login failures (account lockout)

Input Validation

  • [ ] Validate all input against a strict schema — reject unknown fields
  • [ ] Enforce maximum sizes: string length, array size, numeric ranges
  • [ ] Validate content types — reject requests with unexpected Content-Type
  • [ ] Sanitize data used in database queries — use parameterized queries
  • [ ] Never trust client-supplied IDs for ownership — re-verify server-side

HTTPS Everywhere

  • [ ] Redirect HTTP to HTTPS (301 or HSTS preload)
  • [ ] Set Strict-Transport-Security: max-age=31536000; includeSubDomains
  • [ ] Use TLS 1.2+ only — disable TLS 1.0 and 1.1
  • [ ] Use strong cipher suites — disable RC4, 3DES, NULL ciphers

CORS Policy

  • [ ] Whitelist specific allowed origins — avoid * for authenticated APIs
  • [ ] Do not allow arbitrary origins by echoing Origin without validation
  • [ ] Use Access-Control-Allow-Credentials: true only when necessary

Error Message Safety

  • [ ] Do not expose stack traces, internal paths, or database errors to clients
  • [ ] Use generic error messages for authentication failures (Invalid credentials, not User not found)
  • [ ] Return RFC 9457 Problem Details format for structured errors
  • [ ] Log detailed errors server-side; surface only safe summaries to clients

Logging and Monitoring

  • [ ] Log all authentication events (success and failure) with IP and user agent
  • [ ] Alert on abnormal patterns: unusual request rates, credential stuffing patterns, mass enumeration
  • [ ] Never log credentials, tokens, or PII — mask in logs before writing
  • [ ] Correlate logs with a request ID (X-Request-ID) for incident investigation

Security Headers

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Content-Security-Policy: default-src 'self'
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=(), microphone=()

Dependency Security

  • [ ] Run pip audit / npm audit regularly and in CI
  • [ ] Pin dependency versions in production
  • [ ] Subscribe to security advisories for critical dependencies
  • [ ] Remove unused dependencies — each dependency is an attack surface

Protocoles associés

Termes du glossaire associés

Plus dans Security & Authentication