Web Security

API Security Testing: A Practical Guide to Finding API Vulnerabilities

A complete technical guide to API security testing: how to find API endpoints, test for injection, broken authentication, excessive data exposure, mass assignment, and rate limiting bypasses with real examples.

Intermediate15 min·Nyxeara Security Research·2026-09-21·CWE-200
api-securityapi-hackingweb-securityrest-apigraphql-securityowasp-top-10pentesting
Prerequisites
what-is-httpwhat-is-a-url

Short answer

API security testing means finding endpoints an application trusts but doesn't protect — endpoints that accept raw input, return more data than they should, or bypass the authentication that the web pages enforce. APIs are the fastest-growing attack surface because every modern web app is really a dozen APIs dressed up with a UI.

The idea in one minute

Imagine a bank with a teller window at the front and a service door in the alley. The front door has a guard, a metal detector, and a sign saying "please wait to be helped." The service door is unlocked, opens directly into the vault, and nobody checks who walks through. The service door is an API endpoint that the bank's mobile app uses to check balances. The bank secured the UI. They forgot the door their own app uses.

Modern web applications are API-first. The frontend JavaScript, mobile app, and partner integrations all communicate through the same REST or GraphQL endpoints. The browser UI shows you only three account management options, but the API behind it may accept a role parameter, a user_id you shouldn't control, or a limit=9999999 that dumps the entire customer table. API security testing is finding those service doors.

How APIs differ from web pages

APIs are designed for machines, not humans. This makes them fundamentally different security targets:

  • No UI constraints. A dropdown menu limits you to three roles in the browser, but the API accepts any string. The UI hides the DELETE button, but the API still handles DELETE /users/42.
  • Structured input. APIs accept JSON, XML, GraphQL queries, or protocol buffers — not just URL-encoded form data. Each format has its own injection surface.
  • Authentication is delegated. APIs often use tokens (JWT, OAuth 2.0, API keys) instead of session cookies. Token validation, expiration, and scope enforcement are separate vulnerabilities.
  • Documentation is often public. Swagger/OpenAPI specs, Postman collections, and GraphQL introspection schemas leak every endpoint, parameter, and data type.
  • Rate limits are inconsistent. The login page may be throttled, but the password-reset API or the CSV export endpoint may not be.

The API discovery methodology

Before you test an API, you need to find it. Every modern web app exposes APIs — the question is whether they're documented or hidden.

1. Browser DevTools. Open the Network tab. Every XHR/fetch call is an API endpoint. Filter by "XHR" or "Fetch" to see only programmatic requests. Pay attention to endpoint naming patterns: /api/v1/users, /graphql, /rest/v2/.

2. JavaScript source review. Undocumented endpoints are often embedded in JavaScript bundles. Search for strings like "/api/", "api/v", "/internal/", "endpoint:", baseURL, or GraphQL operation names in the compiled JS.

3. Common path patterns. Many APIs follow predictable conventions. Try appending these paths to the base domain:

  • /api/docs, /api/swagger.json, /api/openapi.json, /api/v1/swagger
  • /graphql, /graph, /v1/graphql
  • /api/health, /api/status, /api/ping
  • .well-known/openid-configuration

4. Outdated documentation. An old Swagger spec on a forgotten S3 bucket or the staging environment's Postman collection often reveals endpoints that were never secured in production. Check https://staging.example.com/api/docs.

5. Introspection attacks on GraphQL. GraphQL endpoints frequently leave introspection enabled. Send a query like:

query { __schema { types { name fields { name } } } }

If introspection is on, the entire schema — every query, mutation, and type — is downloadable in a single request. This is the API equivalent of finding the source code on the server.

Common API vulnerabilities

Broken Object Level Authorization (BOLA)

The most common API vulnerability. The API accepts a user-controlled identifier and returns the object without checking ownership.

GET /api/v1/users/me
Authorization: Bearer user_token
→ {"id": 101, "name": "Alice"}

GET /api/v1/users/102
Authorization: Bearer user_token
→ {"id": 102, "name": "Bob", "ssn": "***"}  # BOLA: you're not Bob

Detection: Increment or decrement numeric IDs in endpoints like /users/, /orders/, /invoices/. Try UUIDs from other sessions if you can obtain them. Check whether the response differs in data depth between your own resource and another user's.

Excessive Data Exposure

The API returns the full database row when the UI only needs three fields. The mobile app may not render the ssn field, but it's still in the JSON response and trivially extractable.

GET /api/v1/profile
→ {
    "id": 101,
    "name": "Alice",
    "email": "alice@example.com",
    "ssn": "***",
    "internal_notes": "Flagged for review",
    "password_hash": "$2a$12$..."
  }

Detection: Compare what the browser shows with what the API returns. Every extra field is a potential leak. Pay special attention to fields named role, is_admin, permissions, internal, notes, debug.

Mass Assignment

The API binds every field in the request body to the database model without filtering. If the model has a role or is_admin field, sending it in the request overrides it.

POST /api/v1/register
Content-Type: application/json

{"username": "attacker", "password": "hunter2", "role": "admin", "is_admin": true}

Detection: Add extra fields to every API request: role, is_admin, admin, permissions, group, level, plan, tier, verified, email_verified, balance, credit. Send boolean, numeric, and string versions of privilege-related fields.

Rate limiting bypasses

APIs often throttle the login endpoint but forget to throttle password reset, 2FA verification, or coupon code endpoints.

POST /api/v1/forgot-password
Content-Type: application/json

{"email": "alice@example.com"}
# Try 1000 emails in 60 seconds — no rate limit

Detection: Fuzz every mutation endpoint with rapid requests. The login form is always protected. The POST /api/v1/contact, POST /api/v1/feedback, PUT /api/v1/profile/avatar, and POST /api/v1/coupon/redeem often aren't.

API key and token security

API keys passed in URL query strings (?api_key=abc123) are logged by every proxy, CDN, and analytics tool between the client and server. They appear in browser history, server access logs, and referrer headers. Keys should only be sent in headers:

Authorization: Bearer abc123
X-API-Key: abc123

Check for:

  • API keys in URLs or request bodies
  • JWTs without expiry (exp claim missing)
  • JWTs accepted with algorithm none (security risk)
  • Static API keys that never rotate
  • Keys embedded in mobile apps or JavaScript bundles (trivially extractable)

Server-Side Request Forgery in APIs

APIs that accept URLs — webhook callbacks, import features, avatar URL fields — are SSRF candidates. The attack surface is larger in APIs because APIs accept structured input that often contains URLs nested in JSON:

{
  "profile_picture": "http://169.254.169.254/latest/meta-data/iam/security-credentials/",
  "webhook_url": "http://internal-admin:8080/shutdown"
}

Test every URL-shaped field in API requests, including nested objects and arrays.

GraphQL-specific attacks

GraphQL introduces unique attack vectors beyond REST:

  • Batching attacks. A single GraphQL request can query 10,000 user IDs at once, bypassing per-request rate limits.
query {
  u1: user(id: 1) { email }
  u2: user(id: 2) { email }
  # ... 9998 more
}
  • Depth-based DoS. Deeply nested queries can exhaust server resources.
  • Introspection leaks. Full schema exposure (as discussed above).
  • Field suggestions. Some GraphQL implementations leak valid field names via error messages when you mistype a field.

Verification: real vulnerability or false positive?

For BOLA: confirm that the API actually returns data the requesting user should not have access to. A UUID that is unpredictable but returned when guessed is still a BOLA — security through obscurity is not a mitigation. For excessive data exposure: confirm the extra fields are not used by the frontend. If they are rendered in the DOM, they are accessible. For mass assignment: verify the override actually persists by fetching the resource after mutation.

Real-world impact

The 2019 Capital One breach started with an SSRF in a web application firewall's metadata API endpoint. The US Office of Personnel Management breach used an API that returned excessive data. Every major cloud provider has had a mass assignment vulnerability in their management APIs. API vulnerabilities are not theoretical — they have caused the largest data breaches in history.

Prevention

  • Explicitly validate authorization for every object access — never rely on obfuscated IDs.
  • Define response schemas explicitly; never pass database rows directly to JSON serialization.
  • Use allowlists for mass-assignable fields; reject unknown parameters.
  • Apply rate limits per-authenticated-user, not per-IP, across all mutation endpoints.
  • Disable GraphQL introspection in production.
  • Log every API authentication failure with sufficient context for incident response.
  • Validate and sanitize all URL inputs; block private IP ranges server-side.

Related vulnerabilities

  • SSRF — APIs accepting URL input are the primary entry point for Server-Side Request Forgery.
  • Authentication vulnerabilities — Token handling, session management, and OAuth flows are API security concerns.
  • Injection attacks — APIs accept structured data that requires format-specific validation.
  • Broken access control — The root cause of BOLA is a failure to verify object ownership at the API layer.

Testing methodology (do this safely)

Map every API endpoint the application uses. Test each endpoint for object-level authorization, excessive data, parameter tampering, and rate limiting. For each endpoint, request a resource you own, then modify the identifier to request a resource you don't. Compare response sizes and field count. Only test your own applications or authorized bug bounty programs.

Further reading

Nyxeara perspective

The Nyxeara scanner treats APIs as first-class targets, not secondary surfaces. Every investigation begins with endpoint discovery — crawling the JavaScript bundles, probing for OpenAPI specs, and testing GraphQL introspection. The correlation engine then links a BOLA finding on one endpoint with a mass-assignment finding on another to build a complete attack chain. API vulnerabilities rarely exist in isolation; they compose. A rate limit bypass on the password reset endpoint combined with a BOLA on the user update endpoint is not two findings — it's an account takeover chain, and it should be reported as one.

Published 2026-09-21 · Updated 2026-09-21