Securing a web API
Authentication, authorisation, input handling and abuse protection: the layers that keep an API safe.
On the roadmap:Intermediate · step 7: Secure by design
Lesson 14 of 18 · 10 min read · quiz · exercise
Think in layers
No single control secures an API. Defence comes from several layers, each assuming the others may fail.
Figure SDA-RWS-14-1 · API security layers · © forcsguy.com
1. Transport
Use HTTPS everywhere, with modern TLS and HSTS. Never accept credentials over plain HTTP.
2. Authentication: who is calling?
- Users: OAuth 2.0 / OpenID Connect access tokens, or secure session cookies for browsers (see the earlier lessons).
- Machines: API keys or client credentials, stored as hashes, scoped, and rotatable.
- Send credentials in the
Authorizationheader, never in URLs. - Keep token lifetimes short, support revocation, and protect refresh tokens carefully.
- Add multi-factor authentication for sensitive accounts, and protect login endpoints with rate limits.
3. Authorisation: what may they do?
This is where most real API breaches happen.
- Check on every request, on the server, both the action (role or scope) and the specific object. "Is this user logged in?" is not enough; ask "may this user read order 123?" (broken object-level authorisation is the top API risk).
- Apply least privilege: tokens carry only the scopes they need.
- Never rely on the client hiding buttons.
- Do not expose sequential ids as a security measure. Use authorisation checks (random ids only help a little).
4. Input and output
- Validate every input against a schema: types, lengths, ranges, allowed values. Reject unknown fields (prevents mass assignment, where a caller sets fields like
isAdmin). - Use parameterised queries to prevent SQL injection, and encode output to prevent injection into other systems.
- Limit request size and file types, and scan uploads.
- Return only the fields needed (avoid excessive data exposure), and paginate lists.
- Return generic error messages to clients and keep detail in logs, so errors do not leak internals.
Figure SDA-RWS-14-2 · Two ways a caller proves who it is · © forcsguy.com
Figure SDA-RWS-14-3 · Signing each request with a shared secret (HMAC) · © forcsguy.com
Image: Spanish Coches · CC BY 2.0 · Source · Wikimedia Commons: Peaje - Toll - Péage (5020183265)
5. Abuse protection
- Rate limiting per user, key and IP, with stricter limits on expensive or sensitive endpoints.
- Quotas and timeouts; protect against huge queries (depth limits in GraphQL, page size caps).
- Bot and credential-stuffing defences: lockouts, delays, CAPTCHAs, breached-password checks.
6. Webhooks and service-to-service calls
- Sign outgoing webhooks with an HMAC over the body and a timestamp. Receivers verify the signature in constant time, reject old timestamps and handle events idempotently.
- Between services use mutual TLS or signed tokens, and network policies, instead of trusting "internal" traffic.
7. Browsers: CORS and cookies
- Configure CORS with an explicit allow-list of origins. Never reflect any origin with credentials enabled.
- Cookies:
HttpOnly,Secure,SameSite. Protect state-changing requests from CSRF.
An example worth knowing: in 2021 a flaw in a popular Java logging library (Log4Shell) let attackers run their own code simply by getting a crafted string written to a log.
Figure SDA-RWS-14-4 · How untrusted text became remote code execution · © forcsguy.com
8. Secrets, data and visibility
- Keep secrets in a secrets manager, not in code or images, and rotate them.
- Encrypt sensitive data at rest, and minimise what you store.
- Log authentication events and authorisation failures (never secrets), and alert on anomalies. Keep an inventory of your APIs so old versions and forgotten endpoints do not stay exposed.
- Keep dependencies patched, and test: security tests, dependency scanning, and periodic penetration testing.
Related reading
- MDN: Cross-Origin Resource Sharing (CORS)MDN contributors · MozillaDocumentation
- Introduction to JSON Web TokensAuth0 · jwt.ioDocumentation
- RFC 6749: The OAuth 2.0 Authorization FrameworkIETFDocumentation
- AWS Security BlogAmazon Web Services engineers · Amazon Web ServicesBlogs
Show 6 moreShow fewer
- OWASP Cheat Sheet SeriesOWASP · OWASP FoundationDocumentation
- Google Security BlogGoogle engineers · GoogleBlogs
- How we built rate limiting capable of scaling to millions of domainsCloudflare engineering · CloudflareCase Studies
- OWASP Top 10OWASP · OWASP FoundationDocumentation
- Rate LimitingKeycdn engineers · KeycdnCase Studies
- Scalability and Authentication at TwitchTwitch engineers · TwitchCase Studies
Check your understanding
Question 1 of 3
0 correct so far
A user requests /orders/123 and the server returns the order without checking that it belongs to them. What is this flaw called?
Go deeper
- OWASP API Security Top 10 by OWASP: the most common API security risks with examples
Practise it: Protect the front door
Everything below is already set up for this lesson: change the design, run the traffic, and see whether you meet the goal.
- 1The task
- 2Build and test
Abusive clients send half of 4,000 requests per second. Your single API gateway is saturated by traffic it should never have passed on.
Goal: Under 1% errors for real users.
The gateway has its own capacity. What should refuse excess clients before it?
Try it yourself
Review this endpoint design and list the problems: GET /api/users/42/invoices?api_key=SECRET returns every invoice for user 42 in one response, accepts any JSON body for updates, and has no limits.
Click what a strong design here would need:
More in Real systems
© 2026 forcsguy.com. Original lesson text and diagrams. Books and sites linked above belong to their authors.