Blog - Shellvoide
Published on

API Pentesting Checklist: What Most Teams Miss

WARNING

Disclaimer: This guide is intended for authorized security professionals. All testing techniques described here must only be performed on systems for which you have explicit written permission. Unauthorized API testing is illegal and unethical.

Introduction

A security team wakes up to alerts at 2:17 AM. No malware, no zero-day, just an API endpoint that trusted the wrong object ID. By dawn, customer records are exposed, leadership is in incident mode, and the pentest report from last quarter had marked authentication as "passed." This guide starts where most reports stop: the blind spots that actually get exploited.

APIs are the nervous system of modern applications. Yet most penetration testing engagements treat API security as an afterthought: a few manual Burp Suite requests, a quick OWASP Top 10 scan, and a checkbox marked.

The reality is that API vulnerabilities now account for the majority of data breaches in SaaS and mobile applications. The 2023 Salt Security State of API Security report found that 94% of organizations experienced API security incidents, and 17% had no API security strategy at all.

This guide is a comprehensive, practitioner-level checklist that goes beyond the basics, covering what most teams miss, from JWT misconfigurations to GraphQL introspection abuse to mass assignment in modern frameworks.

API Pentesting Checklist Quick Answer (TL;DR)

If you only have 10 minutes, prioritize these checks first:

  1. Test BOLA/IDOR on every resource endpoint and HTTP method.
  2. Validate function-level authorization on admin and privileged actions.
  3. Probe JWT/OAuth implementation flaws (alg, kid, redirect_uri, state, token reuse).
  4. Stress rate limiting and business flows (OTP brute force, coupon races, workflow skips).
  5. Audit GraphQL for introspection exposure, batching abuse, and resolver-level auth gaps.
  6. Test SSRF in any URL-accepting input (webhook, import, preview, proxy).
  7. Verify security headers, CORS policy, and legacy/shadow API inventory.

Reconnaissance and API Discovery

The first phase most teams rush. You cannot test what you cannot find.

Discovery Checklist

  • Enumerate API endpoints from JS bundles. Modern SPAs embed API calls in minified JS. Use tools like LinkFinder or JSParser.
  • Check Swagger/OpenAPI specs at common paths:
    • /swagger.json, /openapi.json, /api-docs
    • /v1/docs, /v2/swagger, /.well-known/
  • Inspect mobile apps. Decompile APKs/IPAs with jadx, apktool, Frida to extract hardcoded endpoints.
  • Google dorking for APIs:
site:target.com inurl:/api/
site:target.com filetype:json
"target.com" inurl:swagger
  • Wayback Machine: https://web.archive.org/cdx/search/cdx?url=target.com/api/*
  • GitHub/GitLab recon. Search for leaked API schemas, base URLs, tokens:
"target.com" extension:json "swagger"
org:targetcompany "api_key" OR "Authorization"
  • Check CORS headers for reflected origins (may reveal hidden API consumers).
  • Certificate Transparency logs: crt.sh for subdomains that may host internal APIs.
  • Postman public workspaces. Search https://www.postman.com/explore for the target org's published collections.

API Surface Mapping

SourceWhat You Find
Frontend JS BundlesREST endpoints, request schemas
Mobile App (APK/IPA)Internal APIs, hardcoded tokens
Swagger/OpenAPI SpecFull API definition, parameters
GitHub/GitLabLeaked keys, internal base URLs
Wayback MachineDeprecated or legacy endpoints
DNS/Subdomainsapi., internal-api., staging-api.
Network Proxy (Burp/mitmproxy)Runtime API calls from app
Postman PublicPublished collections by dev teams

OWASP API Security Top 10 (2023)

Full Coverage Checklist

#VulnerabilitySeverityWhat to TestOften Missed?
API1Broken Object Level Authorization (BOLA/IDOR)CriticalSubstitute other users' resource IDs in every endpointYes, tested shallowly
API2Broken AuthenticationCriticalToken weaknesses, brute force, credential stuffingPartially
API3Broken Object Property Level AuthorizationHighMass assignment, over-fetching, field-level access controlYes
API4Unrestricted Resource ConsumptionHighRate limits, file size, query complexity, request timeoutsYes
API5Broken Function Level AuthorizationCriticalAccess admin endpoints as low-privilege userPartially
API6Unrestricted Access to Sensitive Business FlowsHighBypass purchase flows, coupon abuse, account takeover chainingFrequently missed
API7Server Side Request Forgery (SSRF)CriticalURL parameters, webhook URLs, import functions, PDF generatorsPartially
API8Security MisconfigurationHighCORS, verbose errors, HTTP methods, debug endpointsPartially
API9Improper Inventory ManagementMediumLegacy /v1 endpoints, shadow APIs, staging APIs in prodYes
API10Unsafe Consumption of APIsHighThird-party API trust, webhook validation, data injection via third partyAlmost always missed

Deep Dive: BOLA/IDOR (API1)

BOLA is the #1 API vulnerability and consistently the most underdiscovered in pentest reports.

Why Teams Miss It

Most testers check one or two obvious endpoints (/users/{id}) and move on. BOLA hides in:

  • Nested resources: GET /accounts/123/transactions/456 (is 456 scoped to 123?)
  • Non-sequential IDs: UUIDs feel safe but the check is still needed
  • POST bodies: {"invoice_id": "other-user-invoice"}
  • HTTP headers: X-User-ID, X-Account-ID passed client-side
  • GraphQL queries with explicit object IDs

BOLA Testing Methodology

# Step 1: Capture your authenticated request
GET /api/v1/orders/ORD-10042 HTTP/1.1
Authorization: Bearer <USER_A_TOKEN>

# Step 2: Get another user's resource ID (register second account)
# Step 3: Use User A's token to access User B's resource
GET /api/v1/orders/ORD-10091 HTTP/1.1
Authorization: Bearer <USER_A_TOKEN>

# Step 4: Check ALL HTTP methods
PUT /api/v1/orders/ORD-10091     # Can you modify it?
DELETE /api/v1/orders/ORD-10091  # Can you delete it?

BOLA Test Matrix

Endpoint PatternHTTP MethodsTest Vectors
/resource/{id}GET, PUT, DELETECross-user ID substitution
/parent/{id}/child/{id}AllParent and child ID swap
POST body with {id}POSTInject foreign resource IDs
Query param ?id=GETParameter manipulation
Header-based identityAllModify X-User-ID header
JWT sub claimAllDecode, modify, re-sign where weak

Deep Dive: Authentication Flaws (API2)

JWT Testing Checklist

JWTs are ubiquitous and often misconfigured.

  • Algorithm confusion (alg: none). Some libraries accept unsigned tokens.
{"alg": "none", "typ": "JWT"}
  • RS256 to HS256 confusion. If server uses RS256, try signing with the public key using HS256.
# Get public key (often exposed at /api/auth/jwks or similar)
# Sign token using public key as HMAC secret
python3 jwt_tool.py <token> -X k -pk public.pem
  • Weak secret brute force
hashcat -a 0 -m 16500 <jwt_token> /usr/share/wordlists/rockyou.txt
  • kid parameter injection where key lookup uses filesystem or DB
{"kid": "../../dev/null", "alg": "HS256"}
  • Expired token acceptance: test exp claim with past timestamps
  • JWT claims not validated: is sub actually tied to the authenticated session?
  • jku/x5u header injection: point to attacker-controlled JWKS endpoint

OAuth 2.0 Testing Checklist

  • redirect_uri manipulation
?redirect_uri=https://evil.com/callback
?redirect_uri=https://legit.com@evil.com/callback
?redirect_uri=https://legit.com%2F%40evil.com
  • state parameter CSRF: is state validated and single-use?
  • Authorization code replay: can authorization codes be reused?
  • Token leakage via Referer: does the token leak in browser redirects?
  • Open redirect chaining in OAuth return flow
  • PKCE downgrade on optional-PKCE implementations
  • Scope escalation by requesting broader privileges

Deep Dive: Mass Assignment/Over-Posting (API3)

Many frameworks (Rails, Spring, Django, NestJS) auto-bind request body fields to model properties. If developers do not explicitly allowlist fields, you can set privileged properties like isAdmin, role, or credit_balance.

# Normal registration request
POST /api/v1/users
{
  "username": "attacker",
  "email": "attacker@evil.com",
  "password": "P@ssw0rd!"
}

# Mass assignment attempt
POST /api/v1/users
{
  "username": "attacker",
  "email": "attacker@evil.com",
  "password": "P@ssw0rd!",
  "role": "admin",
  "isAdmin": true,
  "credit_balance": 99999,
  "verified": true,
  "subscription_tier": "enterprise"
}

Common Mass Assignment Test Fields

FieldTarget Effect
isAdmin, is_admin, adminPrivilege escalation
role, roles[], userTypeRole manipulation
verified, emailVerifiedBypass verification
credit, balance, creditsFinancial fraud
subscription_plan, tierFeature unlock
banned, locked, activeAccount state bypass
created_at, updated_atTimestamp manipulation
owner_id, user_idOwnership reassignment (BOLA)
internal_notesData exfiltration/injection

Deep Dive: Rate Limiting and Resource Consumption (API4)

Most teams test rate limiting with a quick burst test. What is usually missed:

Rate Limit Bypass Techniques

  • IP rotation via headers
X-Forwarded-For: 192.168.1.{1-255}
X-Real-IP: 10.0.0.1
X-Originating-IP: 172.16.0.1
  • Account-level versus IP-level limits: create parallel accounts
  • Endpoint variation bypass (/v1/login, /v2/login, /login)
  • Case variation bypass (/Login versus /login)
  • Parameter padding to break naive keying/caching
  • HTTP method switching where only one method is throttled

Business Logic Rate Limiting Gaps

FunctionTest ScenarioImpact if Missing
Password Reset OTPBrute force 6-digit OTPAccount takeover
2FA CodeBrute force TOTP without lockoutMFA bypass
Promo Code RedemptionParallel redemption raceFinancial loss
File UploadUpload many files rapidlyStorage exhaustion
Email SendingTrigger bulk reset flowsSpam/reputation damage
Search/QueryComplex nested requestsCPU exhaustion
Referral SystemSelf-referral with multiple accountsCredit fraud

GraphQL-Specific Testing

GraphQL has a different attack surface than REST.

GraphQL Recon

# Check if introspection is enabled
curl -X POST https://target.com/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{ __schema { types { name } } }"}'

GraphQL Attack Checklist

  • Introspection enabled in production
  • Batch query attacks (aliasing for brute force)
mutation {
  a1: login(email:"admin@target.com", password:"pass1") { token }
  a2: login(email:"admin@target.com", password:"pass2") { token }
  a3: login(email:"admin@target.com", password:"pass3") { token }
}
  • Query depth attacks for DoS
{ user { posts { comments { author { posts { comments { author { id } } } } } } } }
  • Field suggestion abuse with introspection off
  • IDOR in node IDs (node(id: "dXNlcjoxMjM="))
  • Fragment injection for type confusion edge-cases
  • Directive abuse (@include, @skip)
  • Over-fetching unauthorized fields
  • Mutation authorization gaps
  • Subscription hijacking over WebSocket auth flaws

GraphQL vs REST Attack Surface

AttackRESTGraphQL
IDOR/BOLAURL paramsNode ID encoding
Brute ForceStandard attemptsAlias batching
DoSRequest rateQuery complexity
Schema DisclosureSwagger leakIntrospection
Auth BypassEndpoint-levelResolver-level
InjectionURL/body paramsQuery variables

HTTP Headers and Security Misconfiguration (API8)

Security Headers Checklist

curl -I https://api.target.com/
HeaderExpected ValueRisk if Missing/Misconfigured
Access-Control-Allow-OriginSpecific origin, not * for authenticated APIsCORS data theft
Access-Control-Allow-CredentialsNot true with wildcard originCredential theft
Strict-Transport-Securitymax-age=31536000; includeSubDomainsDowngrade attacks
Content-Typeapplication/json; charset=utf-8MIME sniffing/XSS vectors
X-Content-Type-OptionsnosniffMIME confusion
Cache-Controlno-store for sensitive responsesSensitive cache retention
X-Rate-Limit-*Present and accurateEnumeration/brute-force blind spot
Server/X-Powered-ByAbsent or sanitizedVersion disclosure

CORS Misconfiguration Testing

# Wildcard test
curl -H "Origin: https://evil.com" -I https://api.target.com/user/profile

# Reflected origin test
curl -H "Origin: https://attacker.target.com.evil.com" -I https://api.target.com/user/profile

# Null origin test
curl -H "Origin: null" -I https://api.target.com/user/profile

# Trusted subdomain wildcard test
curl -H "Origin: https://evil.target.com" -I https://api.target.com/user/profile

Business Logic Testing (API6): Most Missed Category

Business logic flaws usually cannot be found by scanners. They require understanding intended user flow and then violating it deliberately.

Commonly Missed Scenarios

ScenarioTest
Checkout race conditionParallel POST /checkout with same cart
Coupon and referral stackingApply multiple discount classes together
Negative quantity purchaseqty: -5 to generate credit
Price tamperingModify cart price fields client-side
Free trial re-enrollmentRe-register after deletion using same identity
Workflow step skippingJump directly from step 1 to step 3
Account merge abuseMerge attacker and victim account artifacts
Refund and keep itemRace refund and fulfillment states
Email normalization bypassuser@gmail.com vs u.s.e.r@gmail.com
Password reset token reuseReuse old token after issuing newer one

Race Condition Test Script

import requests
import threading

TARGET = "https://api.target.com/api/v1/redeem-coupon"
HEADERS = {"Authorization": "Bearer <TOKEN>", "Content-Type": "application/json"}
PAYLOAD = {"coupon_code": "SAVE50", "order_id": "ORD-9912"}


def redeem():
    r = requests.post(TARGET, json=PAYLOAD, headers=HEADERS, timeout=20)
    print(r.status_code, r.text)


threads = [threading.Thread(target=redeem) for _ in range(20)]
for t in threads:
    t.start()
for t in threads:
    t.join()

NOTE

Turbo Intruder in Burp Suite is highly effective for race testing. Its HTTP/2 single-packet strategy can minimize network jitter and improve reproducibility.

SSRF in APIs (API7)

APIs often accept URLs for webhooks, integrations, imports, and previews. Each is a potential SSRF vector.

Common SSRF Entry Points

Endpoint/ParameterExample Payload
POST /webhooks {"url": ...}http://169.254.169.254/latest/meta-data
POST /import {"feed_url": ...}file:///etc/passwd
POST /screenshot {"url": ...}http://internal-service:8080/admin
POST /pdf {"source_url": ...}http://localhost:6379/
GET /proxy?url=http://10.0.0.1/
DNS rebinding targetValidate-then-resolve internal host
SVG upload<image href="http://...">
XML/SAML with DTDXXE to SSRF pivot

Cloud Metadata SSRF Payloads

# AWS
http://169.254.169.254/latest/meta-data/iam/security-credentials/

# GCP (header often required: Metadata-Flavor: Google)
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

# Azure (header often required: Metadata: true)
http://169.254.169.254/metadata/instance?api-version=2021-02-01

API Key and Token Security Checklist

  • API keys in URLs (query strings leak via logs and Referer)
  • Insufficient key entropy and predictable formats
  • Over-privileged key scopes
  • Rotation not enforced (old keys still active)
  • No expiry policy
  • Error messages reveal key format and aid enumeration
  • Keys exposed in mobile binaries

Tools for API Key Discovery

# TruffleHog
trufflehog git https://github.com/target/repo --only-verified

# Gitleaks
gitleaks detect --source /path/to/repo

# GitHub dorking
"target.com" AND ("api_key" OR "apikey" OR "x-api-key") site:github.com

# Frontend JS bundle checks
python3 LinkFinder.py -i https://target.com/app.bundle.js -o results.html

Injection Vulnerabilities in APIs

Injection Test Checklist

Injection TypeTest PayloadsCommon Entry PointsImpact
SQL Injection' OR 1=1--, " OR "1"="1, ; DROP TABLE--Search/filter/ID paramsData exfiltration/deletion
NoSQL Injection{"$gt": ""}, {"$where": "sleep(5000)"}Mongo-style JSON APIsAuth bypass/data leak
Command Injection; id, `whoami, `` sleep 5` ``Conversion/diagnostic endpoints
SSTI{{7*7}}, ${7*7}, <%= 7*7 %>Template/PDF/email renderingRCE
GraphQL InjectionPayloads via query variablesUnsanitized resolversBackend-dependent
LDAP Injection`)(uid=))((uid=*`Authentication/directory lookup
XML/XXEExternal entity declarationsSOAP/XML import/SAMLSSRF/file read/OOB exfil

Mobile API Testing: What Is Different

  • Certificate pinning bypass (Frida, apk-mitm)
  • Root/jailbreak detection bypass and behavior diffing
  • Binary analysis for hidden endpoints (jadx)
  • Hardcoded credentials in APK resources/native libraries
  • Insecure local storage (SharedPreferences, SQLite, logs)
  • Deep link parameter injection into API calls
  • Client-side-only validation assumptions
frida -U -f com.target.app -l ssl-pinning-bypass.js --no-pause

API Testing Toolkit

CategoryTools
Proxy/InterceptBurp Suite Pro, mitmproxy, OWASP ZAP
API Fuzzingffuf, Arjun
GraphQLInQL, graphql-voyager, clairvoyance
JWT Testingjwt_tool, jwt.io, Burp JWT Editor
Race ConditionsTurbo Intruder, Repeater groups
SSRFBurp Collaborator, interactsh
Secret DiscoveryTruffleHog, Gitleaks, SecretFinder
AutomationPostman + Newman, REST-assured
Passive ReconShodan, Censys, FOFA
Documentation AnalysisSwagger Parser, Stoplight

Reporting: What Makes a Good API Pentest Finding

Most findings are reported as generic statements with weak impact analysis. Use a structure that proves exploitability and business risk.

Finding Template

## Finding: [Vuln Class] in [Endpoint]

**Severity:** Critical / High / Medium / Low
**CVSS Score:** X.X (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N)
**CWE:** CWE-XXX

### Description
[Clear, technical description]

### Reproduction Steps
1. Authenticate as standard user
2. Send crafted request
3. Observe unauthorized behavior

### Business Impact
[Concrete impact]

### Affected Endpoints
- POST /api/v1/...
- GET /api/v2/...

### Recommended Remediation
[Specific, actionable fix]

### References
- OWASP API Security Top 10: API1:2023
- CWE-639

Master Checklist Summary

NOTE

Use this as a repeatable baseline before every authorized API pentest.

Pre-Engagement

  • Obtain written authorization and scope document
  • Identify all API versions in scope (v1, v2, legacy, staging)
  • Collect API documentation (Swagger, Postman, internal docs)
  • Set up Burp Suite target scope and logging

Reconnaissance

  • Discover undocumented endpoints (JS analysis, Wayback, GitHub)
  • Map all authentication mechanisms
  • Identify resource types and relationships
  • Enumerate deprecated and versioned paths

Authentication and Authorization

  • BOLA/IDOR on every resource endpoint and method
  • Function-level authorization tests on privileged routes
  • Mass assignment tests on create/update routes
  • JWT weakness checks (alg confusion, weak secret, kid injection)
  • OAuth flow abuse cases
  • API key scope/expiry/entropy/exposure checks

Input Validation

  • SQL, NoSQL, command, LDAP injection testing
  • SSTI in template-driven functionality
  • XXE where XML is accepted
  • SSRF where URL-like input is accepted

Business Logic

  • Race conditions on sensitive flows
  • Workflow step skipping
  • Negative and extreme value abuse
  • Coupon and voucher logic abuse
  • Email normalization and account-linking bypasses

Rate Limiting

  • IP-based bypass checks via forwarding headers
  • OTP/PIN brute-force resilience
  • GraphQL batching and complexity abuse cases

Configuration

  • CORS origin validation
  • Security headers coverage
  • Error message verbosity and leakage
  • HTTP methods and debug endpoints
  • GraphQL introspection in production
  • API inventory completeness (shadow/zombie APIs)

Reporting

  • Reproduction steps are complete and deterministic
  • Business impact is explicit
  • Remediation guidance is specific
  • Findings are mapped to OWASP API Top 10 and CWE

Key Takeaways

  1. BOLA is common and under-tested: test every resource endpoint and method with separate identities.
  2. GraphQL needs a dedicated methodology: introspection, alias batching, depth, and resolver authorization all matter.
  3. Business logic flaws require human analysis: scanners generally miss race conditions and workflow abuse.
  4. Rate limit bypasses are often simple: header/IP trust assumptions fail frequently.
  5. API recon is its own discipline: legacy and shadow endpoints frequently hold the highest risk.
  6. SSRF remains high impact: cloud metadata exposure can be one request away.
  7. JWT implementations are frequently over-trusted: validate assumptions explicitly.

FAQ: API Pentesting Checklist

What is the most common API vulnerability in real pentests?

Broken Object Level Authorization (BOLA/IDOR) is consistently one of the most common and highest-impact issues because it enables cross-account data access with valid credentials.

How is API pentesting different from web app pentesting?

API pentesting focuses more on object-level authorization, workflow abuse, token lifecycle flaws, and machine-to-machine trust boundaries. Unlike traditional UI testing, many API flaws appear only when requests are manipulated directly.

Should GraphQL security testing be separate from REST testing?

Yes. GraphQL has unique attack primitives such as introspection leakage, alias batching, and query complexity abuse that are not covered by standard REST-only test plans.

Can automated scanners fully cover API security testing?

No. Automated scanning helps with baseline checks, but business logic abuse, race conditions, and many authorization flaws require manual scenario-driven testing.

Which OWASP list should API tests map to?

Use the OWASP API Security Top 10 (2023) as the primary taxonomy, and map individual findings to relevant CWE entries for engineering remediation tracking.

References and Further Reading

All techniques should be applied only within authorized penetration testing engagements. Responsible disclosure is encouraged for vulnerabilities discovered in the wild.