LazyHackers.in — Checklist
🔌 API Pentest Checklist
OWASP API Top 10, item by item: scenario · command · steps · the finding · the fix
☰ How to use this guide
APIs fail differently from web pages: the bugs are authorization (BOLA/BFLA), over-exposure, and missing limits — and the UI's restrictions almost never exist on the backend. So test the API directly with curl/Postman/Burp, with two accounts, and read the raw JSON. This guide turns every line of the API checklist into how-to-test. Companion: the API Security deep-dive and the Web checklist (the API is also a web target).
export HTTPS_PROXY=http://127.0.0.1:8080 # route everything through Burp
BASE=https://api.target.tld ; TOKEN_A=...; TOKEN_B=... # two test identities
# Grab the spec if exposed — it is your endpoint map:
curl -s $BASE/openapi.json | jq '.paths | keys'0 Recon & API discovery
Find every endpoint, version and leaked key before testing logic. The spec, JS bundles and old versions hand you most of the surface.
Discover the API surface
# Swagger / OpenAPI / GraphQL discovery
for p in swagger-ui api-docs v3/api-docs openapi.json graphql .well-known/openid-configuration; do
curl -s -o /dev/null -w "%{http_code} $p\n" $BASE/$p ; done
# Endpoints + keys hiding in front-end JS
katana -u https://target.tld -jc -silent | grep -E '/api|/v[0-9]' | anew endpoints.txt
nuclei -l endpoints.txt -t http/exposures/ # tokens, keys, stack traces
# Old versions live alongside current?
for v in v1 v2 v3 internal beta; do curl -s -o /dev/null -w "%{http_code} /$v\n" $BASE/$v/users; doneRecon & discovery — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| API docs exposed (Swagger/OpenAPI) | curl /swagger-ui /api-docs | API documentation exposed |
| GraphQL introspection in prod | introspection query | GraphQL introspection enabled |
| Postman collection / spec leaked | search public Postman/GitHub | API spec leak |
| Hidden endpoints via JS | katana + grep | Undocumented endpoint disclosure |
| Old versions still live | probe /v1 /v2 | Deprecated API version live |
| Internal/admin API internet-reachable | request admin/internal paths | Internal API exposed |
| Mobile app reversed → endpoints/keys | jadx/apktool on APK | Endpoints/keys from mobile binary |
| API keys hardcoded in client | grep JS/APK | Hardcoded API key |
| Sandbox/staging API with prod data | probe staging hosts | Non-prod API with production data |
| Verbose Allow / OPTIONS | curl -X OPTIONS -i | HTTP methods disclosure |
| Errors leak stack/framework/DB | send malformed input | Verbose error disclosure |
| .well-known / discovery leaks config | curl /.well-known/* | Configuration disclosure |
1 Broken object level authorization (BOLA)
API #1 and the most common API critical: the server uses a client-supplied object ID without checking it belongs to you.
BOLA — the two-token method
- Get two accounts (token A, token B). As A, capture a request referencing your object:
GET /api/orders/1001. - Replay it with A's token but B's object ID (or just decrement/increment). B's data returned → BOLA.
- Repeat for body params, query params, headers, nested resources, and batch
ids[]; test read, update and delete. - Automate with Burp Autorize (replays low-priv session against captured requests and diffs).
# Range-sweep object IDs with A's token; flag anything not 403/404
ffuf -u "$BASE/api/orders/FUZZ" -H "Authorization: Bearer $TOKEN_A" \
-w <(seq 1000 1100) -mc 200 -ac -c
# UUIDs are not authz — if leaked elsewhere they are just as swappable.BOLA — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| BOLA read via ID in path | swap /users/{id} | BOLA (read) |
| BOLA update/delete | swap ID on PUT/DELETE | BOLA (modify) |
| BOLA via ID in body | change ID in JSON body | BOLA via request body |
| BOLA via query/header | swap ID in query/header | BOLA via parameter |
| BOLA with UUID/GUID | use leaked/known UUID | BOLA with UUID |
| BOLA on nested resource | swap /orders/{id}/items/{id} | BOLA on nested object |
| BOLA on file/export endpoint | swap document/export ID | BOLA on file/export |
| BOLA via wildcard/batch | ids[]=1,2,3 mixing owners | BOLA via batch parameter |
| Predictable/sequential references | enumerate IDs | Predictable object reference |
| Parent checked, child not | access child of unowned parent | Missing child-object authorisation |
2 Broken authentication
API #2: weak token issuance and JWT handling. Brute the auth endpoint, then attack the token itself.
JWT attacks
jwt_tool <JWT> -T # tamper claims (role, sub) and replay
jwt_tool <JWT> -X a # alg:none family
jwt_tool <JWT> -C -d rockyou.txt # crack weak HS256 secret
jwt_tool <JWT> -X k -pk public.pem # RS256 -> HS256 key confusion
# kid / jku / x5u abuse: point header to attacker-controlled key/URL
# "kid":"../../dev/null" or "jku":"https://attacker.tld/jwks.json"Broken authentication — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| No rate limit on login/token | replay 100× | No authentication rate limit |
| No rate limit on OTP | spam OTP request/verify | No OTP throttling |
| Credential stuffing possible | replay breach combos | Credential stuffing exposure |
| Weak/empty password accepted | register weak/empty | Weak password policy |
| Token issued without credential check | inspect token flow | Improper token issuance |
| JWT alg:none | jwt_tool -X a | JWT alg:none accepted |
| JWT weak HMAC secret | jwt_tool -C | Crackable JWT secret |
| JWT RS256→HS256 confusion | jwt_tool -X k | JWT algorithm confusion |
| JWT signature not verified | edit payload, drop sig | JWT signature not verified |
| JWT kid injection | SQLi/traversal in kid | JWT kid injection |
| JWT expired accepted | replay past exp | JWT expiry not enforced |
| JWT jku/x5u to attacker URL | point header to your JWKS | JWT jku/x5u abuse |
| JWT claims trusted blindly | tamper role/scope claim | Unvalidated JWT claims |
| Refresh token never expires/revocable | reuse after logout | Non-revocable refresh token |
| Refresh reuse not detected | replay rotated refresh | Refresh-token reuse undetected |
| API key in URL | inspect URLs/logs | API key transmitted in URL |
| API key not tied to identity | use key across accounts | Over-shared API key |
| Basic auth over HTTP | capture cleartext | Basic auth over cleartext |
| OAuth redirect_uri not validated | tamper redirect_uri | OAuth redirect_uri validation flaw |
| OAuth missing state | drop state | Missing OAuth state (CSRF) |
| OAuth code reuse | replay auth code | OAuth code not single-use |
| OAuth PKCE not enforced | omit PKCE for public client | PKCE not enforced |
| OAuth scope escalation | tamper scope param | OAuth scope escalation |
| Token not invalidated on logout/pw change | reuse after logout | Token not invalidated |
| mTLS/client cert not enforced | connect without cert | Missing mTLS enforcement |
3 Broken object property level authorization
API #3: property-level authorization. Two halves — the server returns fields you shouldn't see (excessive data exposure), and accepts fields you shouldn't set (mass assignment).
Excessive data exposure & mass assignment
# Excessive exposure — read the FULL JSON, not just what the UI shows
curl -s $BASE/api/users/me -H "Authorization: Bearer $TOKEN_A" | jq .
# look for: passwordHash, internal flags, other users' fields, isAdmin, balance
# Mass assignment — inject privileged fields the UI never sends
curl -s -X PATCH $BASE/api/users/me -H "Authorization: Bearer $TOKEN_A" \
-H 'Content-Type: application/json' \
-d '{"name":"x","role":"admin","isAdmin":true,"verified":true,"ownerId":1}'
# Nested escalation: {"user":{"role":"admin"}}BOPLA — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| More fields than UI uses | read full JSON | Excessive data exposure |
| Sensitive fields in response (hash/tokens) | inspect response | Sensitive field exposure |
| Filtering client-side only | call API directly | Server returns unfiltered object |
| Debug/internal fields leaked | grep isAdmin/creditScore | Internal field disclosure |
| Related-object over-return | inspect list responses | Over-exposure of related data |
| Set role/isAdmin/verified | inject fields | Mass assignment (privilege) |
| Modify userId/ownerId | reassign object owner | Mass assignment (ownership) |
| Set balance/price/status | inject writable field | Mass assignment (state) |
| Override read-only on PUT/PATCH | send read-only fields | Read-only field override |
| Nested object escalation | {"user":{"role":"admin"}} | Nested mass assignment |
4 Unrestricted resource consumption
API #4: no limits = cost, DoS and brute-force enablement. Test rate limits and their bypasses, pagination caps and expensive operations.
# Is there a rate limit, and can it be bypassed?
for i in $(seq 1 200); do curl -s -o /dev/null -w "%{http_code} " $BASE/api/search?q=x \
-H "X-Forwarded-For: 1.2.3.$((RANDOM%255))" ; done # rotate XFF / casing / param
# Pagination / response-size blow-up
curl -s "$BASE/api/items?limit=9999999" -o /dev/null -w "size=%{size_download}\n"Resource consumption — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| No rate limiting on any endpoint | flood requests | Missing rate limiting |
| Rate-limit bypass via header/casing | rotate XFF / change casing | Rate-limit bypass |
| No pagination cap | limit=999999 | Unbounded pagination |
| GraphQL nested-query DoS | deep nested query | GraphQL depth DoS |
| GraphQL batching amplification | array of queries | GraphQL batching abuse |
| GraphQL alias amplification | many aliases of costly field | GraphQL alias amplification |
| Unbounded upload size | huge upload | Unbounded upload (DoS) |
| Expensive op no throttle (export) | spam export/report | Unthrottled expensive operation |
| No limit on OTP/email/SMS | spam sends | Unbounded notification sends |
| ReDoS on regex endpoint | catastrophic regex input | ReDoS |
| Concurrent-request exhaustion | parallel flood | Resource exhaustion |
| No quota on third-party-cost actions | repeat costly action | Missing cost quota |
5 Broken function level authorization (BFLA)
API #5: a normal user reaches admin functions because the UI hides them but the API doesn't check the role.
# Replay an admin-only endpoint with a normal user's token
curl -s -X POST $BASE/api/admin/users -H "Authorization: Bearer $TOKEN_A" -d '{...}' # 200? -> BFLA
# Method swap + override header
curl -X GET $BASE/api/admin/deleteUser?id=5 -H "Authorization: Bearer $TOKEN_A"
curl -X POST $BASE/api/user -H 'X-HTTP-Method-Override: DELETE' -H "Authorization: Bearer $TOKEN_A"BFLA — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| User calls admin-only endpoint | replay as user | BFLA |
| Vertical privesc via direct call | call hidden endpoint | Vertical privilege escalation |
| HTTP method swap bypass | GET where POST blocked | Method-based authz bypass |
| Method-override header bypass | X-HTTP-Method-Override | Method-override bypass |
| Guessable admin endpoints | probe /admin /internal | Guessable privileged endpoint |
| Role check on UI not API | call API directly | Authz enforced client-side only |
| DELETE/PUT for read-only role | mutate as read-only | Excessive method permission |
| Bulk/batch missing authz | bulk action as user | Missing bulk authorisation |
| Different version lacks check | try /v1 of admin call | Authz gap in API version |
6 Unrestricted access to sensitive business flows
API #6: a sensitive flow (purchase, signup, reward) is automatable at scale because there's no anti-automation.
Sensitive business flows — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| Purchase/booking scalping | script the flow at scale | Business-flow automation abuse |
| Mass account creation | bulk signup, no bot control | Missing anti-automation (signup) |
| Referral/reward farming | loop reward flow | Reward farming |
| Comment/review spam at scale | bulk post | Spam-flow abuse |
| No anti-automation on high-value flow | automate transfer/redeem | Missing anti-automation |
| Workflow step skipping | call /confirm directly | Workflow bypass |
| One-time action replayable | resend captured request | Business-action replay |
7 Server-side request forgery (SSRF)
API #7: a parameter that fetches a URL becomes a door into the internal network and cloud metadata.
interactsh-client # OOB host; then point any url/webhook/import param at it
curl -s -X POST $BASE/api/import -d '{"url":"http://<oob>.oast.fun/"}' # callback = SSRF
# Escalate + bypass filters:
url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ # cloud creds
url=http://127.1 url=http://[::] url=http://0x7f000001 url=http://2130706433
# DNS rebinding / 30x redirect to internal when host is allowlistedSSRF — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| SSRF via URL parameter | OOB callback | SSRF |
| SSRF to cloud metadata | 169.254.169.254 | SSRF to cloud metadata |
| SSRF internal port scan | probe internal ports | SSRF internal scanning |
| Blind/OOB SSRF | interactsh callback | Blind SSRF |
| SSRF filter bypass | redirect/rebind/decimal IP | SSRF filter bypass |
| SSRF via upload fetching remote | upload referencing remote URL | SSRF via upload |
| SSRF via PDF/image/headless | inject URL into generator | SSRF via renderer |
8 Security misconfiguration
API #8: CORS, missing headers, verbose errors, exposed debug, weak TLS and parser confusion.
# CORS — reflected origin with credentials is the dangerous one
curl -s -I $BASE/api/me -H 'Origin: https://evil.tld' | grep -i access-control
# ACAO: https://evil.tld + ACAC: true -> exploitable
# Content-type confusion: JSON endpoint that also parses XML -> XXE
curl -s -X POST $BASE/api/x -H 'Content-Type: application/xml' --data @xxe.xmlMisconfiguration — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| CORS wildcard with credentials | Origin test | CORS misconfiguration |
| CORS reflected/arbitrary origin | reflect arbitrary Origin | CORS origin reflection |
| CORS null origin allowed | Origin: null | CORS null-origin allowed |
| Missing security headers | curl -I | Missing security headers |
| Verbose errors in prod | malformed input | Verbose error disclosure |
| Debug endpoints exposed | actuator/metrics/health | Debug endpoint exposed |
| Dangerous HTTP methods | OPTIONS/TRACE | Dangerous methods enabled |
| Default gateway/admin creds | try defaults | Default credentials |
| TLS weak/missing; HTTP accepted | testssl.sh | Weak/missing TLS |
| Unpatched framework (CVE) | nuclei cves | Outdated component |
| Content-type confusion (XML→XXE) | send XML to JSON endpoint | Content-type confusion / XXE |
| Cache stores sensitive response | check Cache-Control | Sensitive response cached |
9 Improper inventory management
API #9: shadow, deprecated and non-prod endpoints that bypass the current controls.
Inventory management — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| Deprecated version still live | probe old versions | Deprecated API version live |
| Shadow/undocumented endpoints | JS/diff discovery | Shadow endpoint |
| Non-prod API internet-exposed | probe dev/staging/uat | Non-prod API exposed |
| Old host serving unpatched API | check historical hosts | Unpatched legacy host |
| Endpoints bypass gateway/auth | compare gateway vs direct | Auth-layer bypass |
| Forgotten beta endpoints | probe beta paths | Weakly-controlled beta endpoint |
10 Unsafe consumption of third-party APIs
API #10: blindly trusting data and redirects from upstream/partner APIs.
Third-party consumption — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| Blindly trusting 3rd-party data | inject via upstream | Unvalidated upstream data |
| No validation on upstream response | malformed upstream | Missing upstream validation |
| Following upstream redirects blindly | redirect to internal | SSRF via upstream redirect |
| Over-scoped/leaked 3rd-party secret | inspect scope/storage | Over-scoped third-party secret |
| Webhook accepted without signature | POST unsigned | Unsigned webhook accepted |
| Injection via partner-sourced data | poison partner field | Injection via partner data |
11 Injection & input validation
APIs hit the same interpreters as web apps — SQL/NoSQL, command, SSTI, XXE, plus JSON type juggling and parser differentials.
sqlmap -r request.req -p id --batch --level 3 # SQLi in body/param
# NoSQL operator injection (JSON)
{"username":{"$ne":null},"password":{"$ne":null}} # auth bypass
# JSON type juggling: send string where int expected, array where string expected
{"id":"1 OR 1=1"} {"role":["admin"]} {"amount":"100e2"}Injection — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| SQL injection | sqlmap | SQL injection |
| NoSQL injection | $ne/$gt operators | NoSQL injection |
| Command injection | ;|`$() in params | OS command injection |
| SSTI in templated response | ${7*7}/{{7*7}} | Server-side template injection |
| XXE via XML/SOAP body | external entity | XXE |
| LDAP/XPath injection | injection in query params | LDAP/XPath injection |
| GraphQL injection (args→backend) | inject via arg | GraphQL injection |
| Header / CRLF injection | %0d%0a in header value | CRLF injection |
| Open redirect via API param | redirect=//evil.tld | Open redirect |
| JSON injection / type juggling | string/int/array swap | JSON type juggling |
| Request smuggling at gateway | smuggler.py | HTTP request smuggling |
| Content-type confusion (parser diff) | alt content-type | Parser differential |
| Stored XSS via API → client/admin | inject, view in client | Stored XSS via API |
12 GraphQL-specific
Run this section only when GraphQL is present. Introspection maps the schema; the bugs are field-level authz, batching and depth.
# Introspection -> full schema
curl -s $BASE/graphql -H 'Content-Type: application/json' \
-d '{"query":"{__schema{queryType{name} types{name fields{name}}}}"}' | jq .
# Batching to bypass rate limit / brute force
[{"query":"mutation{login(u:\"a\",p:\"1\"){t}}"},{"query":"mutation{login(u:\"a\",p:\"2\"){t}}"}]
# Tools: graphw00f (fingerprint), clairvoyance (schema w/o introspection), InQL (Burp)GraphQL — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| Introspection in prod | introspection query | GraphQL introspection enabled |
| Field-level authz missing | query restricted field | Missing field-level authz |
| BOLA/BFLA via query/mutation | swap IDs / call admin mutation | BOLA/BFLA in GraphQL |
| Query depth/complexity DoS | deep nested query | GraphQL depth DoS |
| Batching bypasses rate limit | array of mutations | GraphQL batching abuse |
| Alias overloading amplification | many aliases | Alias amplification |
| Sensitive mutation w/o authz | call mutation as user | Unprotected mutation |
| Errors leak schema/internals | malformed query | Schema disclosure via errors |
| CSRF on GraphQL over GET/form | GET query / form content-type | GraphQL CSRF |
13 Webhooks, async & WebSocket APIs
Run when webhooks/WebSockets are present. The themes: payload spoofing/replay, SSRF via webhook URL config, and missing auth/origin on WS.
Webhook & async/event APIs — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| Webhook unsigned/spoofed | POST forged event | Unsigned webhook accepted |
| Signature missing/bypassable | tamper payload, keep sig | Webhook signature bypass |
| Webhook replay accepted | resend captured event | Webhook replay |
| Webhook URL config → SSRF | set webhook to internal URL | SSRF via webhook config |
| Non-constant-time sig check | timing analysis | Timing-unsafe signature check |
| WebSocket no auth on upgrade | connect without auth | Unauthenticated WebSocket |
| WebSocket no origin check (CSWSH) | cross-origin WS connect | Cross-site WebSocket hijacking |
| WebSocket message-level authz missing | send privileged message | Missing WS message authz |
A SaaS / multi-tenant API
Multi-tenant APIs live or die on tenant isolation. The killer is cross-tenant BOLA via a tamperable tenant ID or token claim.
SaaS / multi-tenant API — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| Cross-tenant object access | swap tenant in request | Cross-tenant access |
| Tenant ID in token/body tamperable | edit tenant claim | Tenant isolation bypass |
| Tenant from client input | change client tenant value | Client-controlled tenant context |
| Shared resource cross-tenant | access other tenant file/job | Cross-tenant resource access |
| API key not tenant-scoped | use key globally | Unscoped API key |
| API key not revoked on removal | reuse after removal | API key not revoked |
| Scope escalation via claim tamper | edit scope claim | Scope escalation |
| Org-admin → super-admin | probe super-admin API | Privilege escalation |
| SSO/SAML replay / audience mismatch | replay assertion | SAML replay |
| OAuth scope broader than UI | inspect granted scopes | Excessive OAuth scope |
| Plan gating client-side only | call gated feature | Client-side feature gating |
| Seat/license manipulation | tamper count | License manipulation |
| Per-tenant rate limit not isolated | noisy-neighbor test | Tenant rate-limit isolation gap |
| Audit log tamperable/missing | act, check log | Audit logging gap |
| Bulk export leaks other tenants | export, inspect scope | Cross-tenant export |
B Banking / fintech API
Money → integrity, race conditions, OTP and account BOLA. Every amount/account/status must be validated and signed server-side.
# Amount/account/status tampering + double-spend race
{"to":"VICTIM","amount":-1000} {"amount":0.001} {"status":"FAILED"}->{"SUCCESS"}
# Fire N parallel withdrawals (Burp single-packet / Turbo Intruder) before balance updatesBanking / fintech API — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| Transfer to arbitrary account | tamper payee | Fund-transfer tampering |
| Negative/decimal rounding abuse | amount=-X / 0.001 | Amount logic flaw |
| Currency mismatch | low/high currency swap | Currency manipulation |
| Race on transfer/withdraw | parallel requests | Race condition (double spend) |
| Race on OTP verify | parallel OTP submits | OTP race condition |
| Transaction-limit bypass (parallel) | parallel over-limit | Limit bypass |
| Account/statement BOLA | swap account | BOLA on account data |
| Predictable transaction reference | enumerate refs | Predictable transaction ID |
| Beneficiary add without OTP/cooling | skip OTP/cooling | Beneficiary control bypass |
| OTP reuse / cross-user | reuse/swap OTP | OTP reuse |
| MPIN/TPIN brute (no lockout) | brute PIN | PIN brute force |
| Forged transaction status accepted | failed→success | Transaction status forgery |
| Payment callback/IPN forging | forge unsigned IPN | Payment callback forgery |
| UPI/IMPS/NEFT replay | replay payment | Payment replay |
| Amount integrity not signed | tamper amount | Missing transaction integrity |
| Loan/credit limit tampering | tamper limit | Credit-limit tampering |
| Interest/EMI manipulation | tamper calc inputs | EMI manipulation |
| KYC BOLA | swap KYC ID | BOLA on KYC |
| Card/CVV/account in response/logs | inspect responses | Financial data exposure |
| Token not device-bound | reuse on other device | Portable token |
| Reward/cashback replay | replay claim | Reward replay |
| PAN/Aadhaar over-exposed | inspect JSON | Regulatory data exposure |
C E-commerce API
Cart, coupon, payment and refund logic via the API. Anything recomputed or trusted client-side is tamperable for free goods/money.
E-commerce API — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| Price tampering | edit price/total | Price tampering |
| Negative quantity | qty=-1 | Negative-quantity flaw |
| Currency manipulation | change currency | Currency manipulation |
| Coupon reuse/stack | reuse single-use | Coupon logic abuse |
| Coupon brute force | ffuf codes | Coupon enumeration |
| Coupon post-payment/discounted | apply late | Coupon application flaw |
| Price set to 0 | price=0 | Zero-price order |
| Tax/shipping removed | drop fields | Tax/shipping bypass |
| Gift card reuse/manipulation | replay gift card | Gift-card manipulation |
| Loyalty points manipulation | add/transfer | Points manipulation |
| Inventory bypass (out-of-stock) | buy OOS item | Inventory bypass |
| Order status manipulation | paid/shipped | Order-status manipulation |
| Payment bypass (no gateway) | confirm w/o payment | Payment bypass |
| Gateway callback tampering | forge callback | Payment callback forgery |
| Partial payment as full | underpay | Partial-payment acceptance |
| Refund amount/destination tamper | edit refund | Refund manipulation |
| Double refund via race | parallel refunds | Refund race |
| Order/invoice/wishlist BOLA | swap IDs | BOLA on commerce objects |
| Delivery address change via BOLA | change other order address | BOLA on delivery |
| Review/rating spoof | post as other user | Review spoofing |
| Seller commission/price manipulation | tamper seller fields | Marketplace manipulation |
D Healthcare API
PHI confidentiality dominates: BOLA on records, unauthenticated report access, over-exposure.
Healthcare API — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| PHI/record BOLA | swap patient/record ID | BOLA on PHI |
| Prescription/lab report BOLA | swap document ID | BOLA on medical documents |
| Booking on behalf of another | change patient ID | Booking authz bypass |
| Doctor/patient role bypass | cross-role call | Role boundary bypass |
| PII/PHI excessive exposure | inspect JSON | PHI over-exposure |
| Sensitive data in URL / unexpiring link | inspect links | Non-expiring sensitive link |
| Consent/access-log missing | access w/o consent | Consent/audit gap |
| Bulk patient export authz missing | bulk export as user | Missing bulk-export authz |
E Internal / admin / microservice APIs
Internal/microservice APIs often trust the caller blindly — spoofable identity headers and missing service-to-service auth are the wins.
# Inter-service trust header spoofing — claim to be an internal/admin caller
curl -s $BASE/internal/users -H 'X-User-Id: 1' -H 'X-Role: admin' -H 'X-Forwarded-For: 127.0.0.1'Internal / admin / microservice API — full coverage
| Checklist item | How to test | Report as |
|---|---|---|
| Internal API internet-exposed | probe internal hosts | Internal API exposed |
| Service trusts caller blindly | call without token/mTLS | Missing service auth |
| Admin endpoint w/o admin role | call as user | BFLA on internal API |
| Default service credentials | try defaults | Default credentials |
| Impersonate / act-as abuse | test impersonation scope | Impersonation abuse |
| User-management BOLA/BFLA | swap/escalate | BOLA/BFLA on user management |
| Audit log clear via lower role | attempt clear | Audit-log tampering |
| Queue/event injection w/o authz | inject event | Event injection |
| Config/secrets endpoint exposed | request config | Secrets endpoint exposed |
| Trust header spoofable | X-User-Id/X-Role | Spoofable identity header |
✓ Coverage map & how to run it
Run sections 0–11 on every API; add 12/13 when GraphQL/webhooks/WebSockets exist; finish with the category block that matches the product.
| Section | Run on | Focus |
|---|---|---|
| Universal 0–11 | Every API | BOLA/BFLA, auth/JWT, BOPLA, consumption, SSRF, misconfig, inventory, 3rd-party, injection |
| GraphQL 12 | GraphQL stacks | Introspection, field authz, depth/batching |
| Webhook/WS 13 | Event/realtime APIs | Signature, replay, SSRF, CSWSH |
| SaaS | Multi-tenant | Cross-tenant BOLA, token/scope, key revocation |
| Banking | Fintech | Transaction integrity, races, OTP, account BOLA |
| E-commerce | Stores | Price/coupon/payment/refund, order BOLA |
| Healthcare | Health APIs | PHI BOLA, over-exposure, consent |
| Internal | Microservices | Service trust, BFLA, header spoofing |
The through-line for APIs: authorization is the bug. Test object access (BOLA) and function access (BFLA) with two accounts against the backend directly, read the full JSON for over-exposure, and never assume the UI's limits are the server's. Tick a box only when you've run the test and recorded the result; the finding names are written to paste straight into the report.