Skip to main content
Career Paths
Concepts
Api Security
The Simplified Tech

Role-based learning paths to help you master cloud engineering with clarity and confidence.

Product

  • Career Paths
  • Interview Prep
  • Scenarios
  • AI Features
  • Cloud Comparison
  • Resume Builder
  • Pricing

Community

  • Join Discord

Account

  • Dashboard
  • Credits
  • Updates
  • Sign in
  • Sign up
  • Contact Support

Stay updated

Get the latest learning tips and updates. No spam, ever.

Terms of ServicePrivacy Policy

© 2026 TheSimplifiedTech. All rights reserved.

BackBack
Interactive Explainer

API Security

How to design and operate secure APIs — covering authentication, authorisation, rate limiting, input validation, the OWASP API Security Top 10, and API gateway patterns.

🎯Key Takeaways
BOLA (Broken Object Level Authorization) is the #1 API vulnerability — always include ownership constraints in DB queries, never check after fetching.
Authentication verifies identity; authorisation checks what that identity can access — both are required at every endpoint.
Use UUIDs for resource IDs — sequential integers enable trivial enumeration attacks.
Rate limiting must be at the API gateway layer — application-level rate limiting can be bypassed.
Validate all input strictly: schema, content type, field allowlist, pagination limits.
Never bind request bodies directly to data models — use explicit field allowlists to prevent mass assignment.
Maintain an API inventory and sunset old versions — shadow APIs and old v1 endpoints are consistently exploited.
Return 404 (not 403) when a resource is not found or not accessible — do not confirm resource existence to unauthorised callers.

API Security

How to design and operate secure APIs — covering authentication, authorisation, rate limiting, input validation, the OWASP API Security Top 10, and API gateway patterns.

~9 min read
Be the first to complete!
Why this matters

APIs are the attack surface of modern applications. Broken authentication, missing authorisation checks, and lack of rate limiting allow attackers to enumerate data, bypass access controls, and abuse functionality at scale.

Without this knowledge

Attackers can enumerate user accounts, access other users' data via IDOR, bypass payment flows, scrape your entire database, or cause denial of service — all through your own API.

With this knowledge

Every API endpoint is protected by authentication, authorisation at the object and field level, rate limiting, input validation, and monitoring. Abuse is detected and blocked before it causes significant damage.

What you'll learn
  • BOLA (Broken Object Level Authorization) is the #1 API vulnerability — always include ownership constraints in DB queries, never check after fetching.
  • Authentication verifies identity; authorisation checks what that identity can access — both are required at every endpoint.
  • Use UUIDs for resource IDs — sequential integers enable trivial enumeration attacks.
  • Rate limiting must be at the API gateway layer — application-level rate limiting can be bypassed.
  • Validate all input strictly: schema, content type, field allowlist, pagination limits.
  • Never bind request bodies directly to data models — use explicit field allowlists to prevent mass assignment.
  • Maintain an API inventory and sunset old versions — shadow APIs and old v1 endpoints are consistently exploited.
  • Return 404 (not 403) when a resource is not found or not accessible — do not confirm resource existence to unauthorised callers.

Lesson outline

OWASP API Security Top 10: The Most Common API Vulnerabilities

The OWASP API Security Top 10 (2023) documents the most critical API security risks. Unlike the web application Top 10, these are specific to API patterns.

#VulnerabilityWhat it meansExample
API1Broken Object Level Authorization (BOLA/IDOR)API accepts user-controlled IDs without checking if caller owns that objectGET /invoices/1234 works for any user, not just the invoice owner
API2Broken AuthenticationWeak tokens, no expiry, predictable secrets, missing MFA for sensitive opsJWT signed with "secret", API keys in URLs, no refresh token rotation
API3Broken Object Property Level AuthorizationAPI returns or accepts more fields than the caller should see/setUser updates their profile and can set role: "admin" because it is not filtered
API4Unrestricted Resource ConsumptionNo rate limiting, pagination limits, or payload size limitsAttacker downloads entire user database via paginated /users?page=N
API5Broken Function Level AuthorizationAdmin endpoints not properly restricted to admin rolesDELETE /admin/users/{id} returns 200 for regular users
API6Unrestricted Access to Sensitive Business FlowsAutomation-accessible flows designed for human use onlyBot buys all concert tickets in milliseconds via the ticket purchase API
API7Server-Side Request Forgery (SSRF)API fetches user-supplied URLs, allowing access to internal servicesPOST /fetch?url=http://169.254.169.254/metadata returns AWS instance metadata
API8Security MisconfigurationVerbose error messages, debug endpoints, permissive CORS, missing security headersStack traces in 500 errors reveal DB schema; CORS allows *
API9Improper Inventory ManagementOld API versions still running, shadow APIs, unauthenticated test endpoints/v1/users still reachable after v2 launched, with weaker auth
API10Unsafe Consumption of APIsTrusting data from third-party APIs without validationWebhook from payment provider used to set order status without signature verification
Pattern

Authentication and Authorisation Patterns

Authentication (who are you?) and authorisation (what are you allowed to do?) are distinct layers. Both must be applied at every API endpoint.

Authentication mechanisms for APIs

  • JWT (JSON Web Token) — Stateless, self-contained token with claims. Signed (RS256/ES256 — not HS256 with shared secret). Validate signature, expiry, issuer, audience on every request.
  • OAuth 2.0 + OIDC — Industry standard for delegated access. Use PKCE for SPAs/mobile. Client credentials flow for M2M. Never use implicit flow.
  • API Keys — Simple but limited — no expiry by default, hard to rotate, no user identity. Use for server-to-server only, with rate limiting per key.
  • mTLS — Certificate-based — client presents cert, server verifies. Ideal for service-to-service in zero-trust environments.

BOLA is the #1 API vulnerability — authorise at object level, not just endpoint level

Middleware that checks "is the user authenticated and has the READER role" does not prevent BOLA. You must also check "does this user own or have permission to access this specific resource ID?" This check must happen in every handler that accepts a user-controlled ID.

BOLA-safe resource access pattern

→

01

Extract the resource ID from the request (path param, query param, or body)

→

02

Extract the caller's identity from the validated JWT/session

→

03

Query the database: SELECT * FROM invoices WHERE id = ? AND owner_id = ?

→

04

If the result is empty, return 404 (not 403 — do not confirm the resource exists)

05

Never query by ID alone and then check ownership afterwards — use the ownership constraint in the query itself

1

Extract the resource ID from the request (path param, query param, or body)

2

Extract the caller's identity from the validated JWT/session

3

Query the database: SELECT * FROM invoices WHERE id = ? AND owner_id = ?

4

If the result is empty, return 404 (not 403 — do not confirm the resource exists)

5

Never query by ID alone and then check ownership afterwards — use the ownership constraint in the query itself

bola-safe-pattern.ts
1// BOLA-vulnerable vs BOLA-safe pattern (Node.js / Express)
2
3// ❌ VULNERABLE — fetches by ID, then checks ownership
VULNERABLE — fetches first, checks ownership after
4app.get('/api/invoices/:id', authenticate, async (req, res) => {
5 const invoice = await db.query(
6 'SELECT * FROM invoices WHERE id = $1',
7 [req.params.id] // Any authenticated user can fetch any invoice
8 );
9 if (!invoice) return res.status(404).json({ error: 'Not found' });
10
11 // This check is TOO LATE — the data was already fetched
12 if (invoice.owner_id !== req.user.id) {
13 return res.status(403).json({ error: 'Forbidden' });
14 }
15 return res.json(invoice);
16});
17
18// ✅ SAFE — ownership constraint is part of the query
19app.get('/api/invoices/:id', authenticate, async (req, res) => {
SAFE — ownership is a WHERE condition, not an afterthought
20 const invoice = await db.query(
21 'SELECT * FROM invoices WHERE id = $1 AND owner_id = $2',
22 [req.params.id, req.user.id] // Returns nothing if ID doesn't belong to caller
23 );
Return 404, not 403 — do not confirm the resource exists
24 if (!invoice) return res.status(404).json({ error: 'Not found' });
25 // 404, not 403 — don't confirm the resource exists to unauthorised callers
26 return res.json(invoice);
27});
28
29// Also: validate and sanitise req.params.id
30// Reject non-UUID formats before hitting the database
31function validateInvoiceId(id: string): boolean {
32 return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(id);
33}

Rate Limiting, Throttling, and Abuse Prevention

Rate limiting protects APIs from brute force, credential stuffing, scraping, and denial of service. Different endpoints need different limits.

Endpoint TypeRecommended LimitWhy
Login / auth5 attempts / 15 min per IP + per usernamePrevents credential stuffing and brute force
Password reset3 requests / hour per emailPrevents email flooding and token enumeration
Public read API1,000 req/min per API keyPrevents scraping, protects backend load
Authenticated write100 req/min per userPrevents automated abuse of write operations
File upload10 uploads/hour per user + size limitPrevents storage abuse and DoS via large payloads
Search / full-text30 req/min per userSearch is expensive — prevents DB overload
Webhook deliveryExponential backoff, max 10 retriesPrevents retry storms from unreachable endpoints

Rate limiting must be at the API gateway — not just the application

Application-level rate limiting (Express rate-limit middleware) is bypassed if an attacker sends requests directly to your service, skipping the gateway. Implement rate limiting at the API gateway (Kong, AWS API Gateway, Nginx) so it applies regardless of how requests arrive.

kong-api-security.yaml
1# Kong API Gateway — rate limiting + key auth + request validation
2# kong.yaml (declarative config)
3
4services:
5 - name: invoices-api
6 url: http://invoices-service:3000
7 routes:
8 - name: invoices-route
9 paths: [/api/v1/invoices]
10 methods: [GET, POST, PUT, DELETE]
11 plugins:
12 # Authentication
13 - name: jwt
14 config:
JWT validation — verify signature, expiry, not-before
15 claims_to_verify: [exp, nbf]
16 key_claim_name: kid
17
18 # Rate limiting per consumer (authenticated user)
19 - name: rate-limiting
20 config:
21 minute: 100 # 100 req/min per consumer
Redis backend — rate limit state shared across all gateway instances
22 hour: 3000
fault_tolerant: false — if Redis is down, reject requests (fail closed)
23 policy: redis # Use Redis for distributed counting
24 fault_tolerant: false # Fail closed if Redis is down
25
26 # Stricter limit for auth endpoints
27 - name: rate-limiting
28 instance_name: auth-strict
29 config:
30 minute: 5
31 second: 1
32 route: login-route
33
34 # Request size limit — prevent payload-based DoS
35 - name: request-size-limiting
36 config:
37 allowed_payload_size: 1 # 1 MB max
38
39 # Security headers
40 - name: response-transformer
41 config:
42 add:
43 headers:
44 - "X-Content-Type-Options: nosniff"
45 - "X-Frame-Options: DENY"
46 - "Strict-Transport-Security: max-age=31536000"

Input Validation and Output Encoding

APIs must validate all input — not just for type correctness but for security. Invalid input can cause injection attacks, SSRF, path traversal, and business logic abuse.

Input validation rules

  • Validate schema strictly — Use JSON Schema or Zod/Joi validation. Reject requests with unexpected fields (allowlist, not denylist). Fail fast before business logic runs.
  • Validate content type — Reject requests where Content-Type does not match body. A multipart/form-data body sent as application/json can bypass validation.
  • URL and redirect validation — Any API that fetches a user-supplied URL must validate against an allowlist of domains — prevents SSRF (API7).
  • File upload validation — Validate magic bytes (not just file extension), scan with antivirus, store outside webroot, rename on upload, enforce size limits.
  • Pagination and ordering — Validate page size limits (max 100), validate sort field against allowlist of column names (prevents SQL injection via ORDER BY).

Mass assignment: never bind request body directly to your data model

If your ORM or framework automatically maps JSON body fields to model properties, an attacker can set fields they should not have access to (e.g., isAdmin: true, balance: 999999). Always use an explicit allowlist of fields that are permitted to be set via each endpoint.

API Versioning, Inventory, and Deprecation Security

Old API versions are a major attack surface. OWASP API9 (Improper Inventory Management) is consistently exploited because organisations lose track of what APIs they expose.

API inventory best practices

  • Maintain an API inventory — Every API endpoint — internal, external, partner-facing — must be documented in a central registry with owner, auth requirements, and deprecation date.
  • Deprecate versions aggressively — Set a hard sunset date when releasing a new API version. After sunset, return 410 Gone — not 200. Monitor traffic to old versions and contact callers before shutdown.
  • Scan for shadow APIs — Use API discovery tools (42Crunch, Salt Security, or network traffic analysis) to find undocumented endpoints that bypass your security controls.
  • Apply the same security to all versions — v1 endpoints that still receive traffic must have the same authentication, rate limiting, and authorisation as v2 — not the weaker controls they launched with.
How this might come up in interviews

API security is a core topic in backend engineering interviews, security architecture reviews, and any role where you design or review APIs. BOLA/IDOR is almost always mentioned.

Common questions:

  • What is BOLA and how do you prevent it?
  • How would you design rate limiting for a login endpoint?
  • What is the OWASP API Security Top 10?
  • A user can see another user's data by changing the ID in the URL. What went wrong and how do you fix it?
  • How do you prevent mass assignment vulnerabilities in a REST API?

Strong answer: Explains the difference between authentication and authorisation, knows BOLA by name, mentions rate limiting at the gateway layer, and understands mass assignment.

Red flags: Thinking authentication alone is sufficient for API security, not knowing what BOLA means, or suggesting that HTTPS prevents all API attacks.

Quick check · API Security

1 / 3

A user changes their request from GET /api/orders/1001 to GET /api/orders/1002 and gets another user's order data. Which OWASP API vulnerability is this?

Key takeaways

  • BOLA (Broken Object Level Authorization) is the #1 API vulnerability — always include ownership constraints in DB queries, never check after fetching.
  • Authentication verifies identity; authorisation checks what that identity can access — both are required at every endpoint.
  • Use UUIDs for resource IDs — sequential integers enable trivial enumeration attacks.
  • Rate limiting must be at the API gateway layer — application-level rate limiting can be bypassed.
  • Validate all input strictly: schema, content type, field allowlist, pagination limits.
  • Never bind request bodies directly to data models — use explicit field allowlists to prevent mass assignment.
  • Maintain an API inventory and sunset old versions — shadow APIs and old v1 endpoints are consistently exploited.
  • Return 404 (not 403) when a resource is not found or not accessible — do not confirm resource existence to unauthorised callers.
Before you move on: can you answer these?

Explain BOLA with a real code example and how to fix it.

BOLA (Broken Object Level Authorization) occurs when an API accepts a user-controlled resource ID without verifying the caller owns that resource. Example: GET /api/orders/1234 — if any authenticated user can access any order ID, an attacker can enumerate all orders by incrementing the ID. Fix: include ownership in the query — SELECT * FROM orders WHERE id = ? AND user_id = ?. Return 404 (not 403) if not found to avoid confirming the resource exists. Use non-sequential UUIDs to make enumeration impractical even without the fix.

What is the difference between API2 (Broken Authentication) and API5 (Broken Function Level Authorization)?

API2 (Broken Authentication) is about identity verification failing — weak tokens, no expiry, no signature validation, missing MFA. The API cannot reliably determine who the caller is. API5 (Broken Function Level Authorization) assumes authentication works, but checks whether a normal user can call admin functions — DELETE /admin/users, POST /admin/config. The caller is correctly identified, but the role/permission check for the specific operation is missing or misconfigured.

From the books

The Web Application Hacker's Handbook (Stuttard & Pinto)

Foundational text covering API and web application attack techniques from the attacker's perspective. Understanding how attacks work is essential for building effective defences.

OWASP API Security Project (owasp.org/api-security)

The authoritative reference for API security vulnerabilities and mitigations. The Top 10 list is updated regularly and includes detailed attack scenarios and prevention guidance.

🧠Mental Model

💡 Analogy

A bouncer, a guest list, and a drink ticket system

⚡ Core Idea

Authentication is the bouncer checking your ID. Authorisation is the guest list — even if you got past the bouncer, some areas require a VIP wristband. Rate limiting is the drink ticket system — you get N tickets, then you wait. All three must work together: a bouncer with no guest list or a guest list with no bouncer are both failures.

🎯 Why It Matters

APIs are the primary interface to your application's data and business logic. A single BOLA bug can expose every user's data. A missing rate limit allows your entire database to be scraped in hours. API security is not optional — it is the security layer for the modern web.

Ready to see how this works in the cloud?

Switch to Career Paths for structured paths (e.g. Developer, DevOps) and provider-specific lessons.

View role-based paths

Sign in to track your progress and mark lessons complete.

Discussion

Questions? Discuss in the community or start a thread below.

Join Discord

In-app Q&A

Sign in to start or join a thread.