APIs rarely fail in isolation. In production, they sit behind reverse proxies and load balancers, depend on CI/CD pipelines and container images, talk to databases and message queues, and get observed (sometimes poorly) through logs and dashboards. When an incident happens—data exposure, account takeover, downtime—the root cause is often found in the seam between code and infrastructure.

This guide is written for system administrators and developers who build and operate APIs together. It focuses on practical controls you can apply without turning delivery into a months-long compliance project.


1) HTTPS everywhere (and configured correctly)

“Using HTTPS” is not the same as “being safe in transit.” Teams frequently terminate TLS at a CDN or reverse proxy and accidentally leave gaps behind it.

What to do:

  • Enforce HTTPS end-to-end where feasible, or at least from client → edge with hardened internal transport.
  • Prefer TLS 1.3 (TLS 1.2 minimum).
  • Enable HSTS to prevent downgrade attacks.
  • Disable legacy protocols and weak cipher suites.
  • If you’re behind a proxy, handle forwarded headers carefully (e.g., don’t trust X-Forwarded-Proto unless it’s set by infrastructure you control).

2) Authentication that survives real attackers (not just happy-path users)

Most API breaches don’t start with “cryptography was broken.” They start with tokens that are too permissive, too long-lived, or incorrectly validated.

What to do:

  • Use OAuth 2.0 + OpenID Connect when you have multiple apps, users, or third-party access patterns.
  • Keep access tokens short-lived; rotate refresh tokens where applicable.
  • If using JWTs, validate signature, issuer (iss), audience (aud), expiration (exp), and time constraints (nbf) consistently.
  • Require MFA for admin consoles and privileged identities.

A common production mistake: accepting tokens without checking audience/issuer, which turns “valid somewhere” into “valid everywhere.”


3) Authorization (the quiet source of the worst incidents)

Authentication answers “who are you?” Authorization answers “what are you allowed to do?” Many serious API exposures come from object-level authorization failures—the classic “change an ID and read someone else’s data.”

What to do:

  • Implement RBAC (role-based) or ABAC (attribute-based) based on your domain.
  • Enforce authorization checks on every request, not only at login.
  • Guard access to individual resources (anti-IDOR/BOLA patterns).
  • Default to least privilege.

For operators: watch for spikes in 403s, unusual access patterns, and enumeration-like behavior.


4) Rate limiting and throttling (start at the edge)

If rate limiting only happens inside the application, the backend still pays the cost of parsing, routing, and often database work—exactly what abuse traffic is designed to trigger.

What to do:

  • Apply rate limits at the reverse proxy / API gateway first.
  • Use separate policies for:
    • login / password reset
    • search endpoints
    • exports / reports
    • file uploads
  • Rate limit by IP + token + client/app identity where possible.
  • Return consistent HTTP 429 and encourage client backoff.

5) Input validation plus hard limits (security and cost control)

Input validation isn’t just about SQL injection. It’s also about preventing APIs from becoming an accidental denial-of-service machine.

What to do:

  • Validate request bodies using schemas (OpenAPI/JSON Schema or equivalent).
  • Prefer allowlists over “sanitize everything.”
  • Set strict limits:
    • max body size
    • max parameter count
    • max string lengths
    • upload size/type restrictions
  • Use parameterized queries; avoid risky deserialization patterns.

From the sysadmin side: enforce request size/timeouts at the proxy to stop oversized payloads before they hit the app.


6) Error handling that doesn’t leak your internal map

Verbose errors help attackers. Stack traces, SQL errors, and internal paths often turn a minor bug into an exploit roadmap.

What to do:

  • Return clean, consistent error responses to clients.
  • Log detailed errors internally—securely.
  • Disable debug modes in production.
  • Use correct HTTP status codes (400/401/403/404/429/500) consistently.

Standardizing error formats also improves alerting and incident response.


7) Observability that’s useful—and safe

Without visibility, teams can’t detect abuse early or reconstruct incidents reliably. But logging the wrong things can create its own breach.

What to log:

  • request/correlation ID
  • endpoint + method
  • status code
  • latency
  • client/app/user identifiers (when appropriate)
  • limited IP/user-agent data (consider privacy requirements)

What not to log:

  • passwords
  • tokens
  • cookies
  • API keys
  • sensitive payload fields

What to alert on:

  • spikes in 401/403/429
  • sustained 5xx rates
  • unusual latency patterns
  • bursty traffic on sensitive endpoints
  • resource enumeration behavior (many IDs in short time)

8) Dependencies, base images, and patching (the supply chain reality)

Modern APIs are assembled from frameworks, libraries, and container images. “We didn’t change anything” is exactly how vulnerable components live forever.

What to do:

  • Automate dependency checks in CI (language ecosystem tools + SCA scanning).
  • Keep base images and runtimes patched.
  • Pin versions with lockfiles and update intentionally.
  • Remove unused dependencies.

Operationally, define patch windows and emergency procedures for critical CVEs.


9) Secrets management: out of repos, out of images, and rotated

Hardcoded secrets are still one of the fastest paths to compromise—especially through leaked repos, CI logs, artifact stores, or container images.

What to do:

  • Use a secrets manager (Vault or a cloud equivalent).
  • Separate secrets by environment (dev/staging/prod).
  • Rotate keys and audit access.
  • Use least-privilege service accounts and short-lived credentials where possible.

10) Infrastructure controls: WAF, mTLS (where needed), and segmentation

Once an API becomes business-critical, two controls typically deliver high ROI:

WAF / API gateway protections

  • bot mitigation and abuse filtering
  • endpoint-specific rules
  • IP reputation and anomaly detection

Internal trust boundaries

  • network segmentation (reduce lateral movement)
  • egress controls (not everything should call anywhere)
  • mTLS between sensitive services (where it fits your architecture)

These don’t replace secure code—but they can dramatically reduce blast radius.


A “Sysadmin + Dev” pre-release checklist

  • TLS hardened, HTTPS enforced, HSTS enabled
  • Tokens validated correctly (issuer/audience/expiry), short-lived sessions
  • Object-level authorization checks in place (anti-IDOR/BOLA)
  • Rate limits at the edge + per-endpoint policies
  • Request size/timeouts enforced at proxy and app
  • Error responses sanitized; debug disabled
  • Logs safe (no secrets) + actionable alerts enabled
  • Dependencies and container images scanned and patched
  • Secrets stored in a manager and rotated
  • WAF/gateway controls and segmentation where criticality demands

FAQ

Where should rate limiting live: the app or the proxy?
Both help, but the reverse proxy/API gateway should be first. It blocks abuse before the backend burns CPU and database capacity.

What is IDOR/BOLA, and why does it keep happening?
It’s when an authenticated user accesses someone else’s resources by changing identifiers (like userId or invoiceId). It happens when authorization isn’t enforced at the resource level.

What should operators monitor to detect API attacks early?
Spikes in 401/403/429, growth in 5xx errors, unusual latency, hot endpoints, and patterns of enumeration (many distinct IDs in short bursts).

What’s the fastest high-impact improvement for an API already in production?
Edge rate limiting plus clean logging/alerting. It reduces abuse immediately and shortens response time when something goes wrong.

Scroll to Top