← Back to Blog
Guides10 min read

A Practical Guide to API Security Testing

December 12, 2025

APIs are the backbone of modern applications, and they are also consistently among the most poorly secured components. This guide covers the techniques and mindset required to find real vulnerabilities in REST and GraphQL APIs — not just running a scanner and calling it done.

Broken Object-Level Authorization (BOLA/IDOR)

BOLA — listed as the number one risk in the OWASP API Security Top 10 — occurs when an API uses user-supplied identifiers to retrieve objects without verifying that the requesting user has the right to access that specific object. The fix sounds trivial, but the prevalence of the bug in production systems tells a different story. Any endpoint that accepts an identifier in the URL, query string, or request body is a candidate: GET /api/invoices/8471, GET /api/users/29/documents/5, or POST /api/orders/lookup with an orderId in the body.

Testing methodology: authenticate as User A, capture a valid object identifier belonging to User A, then replay the request using User B's session. If the server returns User A's resource to User B, the endpoint is vulnerable. Automate this across every identified endpoint using Burp Suite's Autorize extension or a custom script that pairs two session tokens and flags divergent response bodies. Pay particular attention to integer IDs — attackers can enumerate them sequentially — but GUIDs are not a defense; they reduce guessability but do not replace authorization checks.

BOLA also appears in indirect references. An API might use a predictable hash or a base64-encoded composite key. Decode every opaque identifier you encounter; you will frequently find structured data that reveals the underlying resource model and makes enumeration straightforward. Check for horizontal privilege escalation (same role, different tenant) separately from vertical privilege escalation (different roles).

Broken Authentication and Token Handling

Authentication flaws in APIs differ from traditional web application authentication because there is no session cookie managed by the browser — the client handles token storage and transmission. Common issues include accepting tokens in multiple places (header and query parameter simultaneously), not invalidating tokens on logout, using insufficiently random API keys, and failing to scope tokens to the minimum required permissions.

Test for credential stuffing surface area: does the login endpoint have rate limiting? Does it lock accounts or add delays after repeated failures? Does a password_reset endpoint leak whether an email address is registered via different response codes or bodies? Try sending authentication requests with the Authorization header missing, empty, set to a literal null string, or containing a token from a different environment — staging tokens used against production APIs are a real finding.

OAuth 2.0 flows deserve particular attention. Test the authorization code flow for open redirect vulnerabilities in the redirect_uri parameter — if the server accepts a wildcard or a suffix match, an attacker can steal authorization codes. Check whether PKCE is enforced on public clients. Verify that refresh tokens are rotated on use and invalidated when a new token is issued, preventing replay of captured tokens.

Excessive Data Exposure and Mass Assignment

Excessive data exposure happens when an API returns the full internal model object and relies on the client to filter fields before rendering them. The client might only display name and email in the UI, but the raw API response contains password_hash, internal_notes, credit_card_last4, and is_admin. Intercept and inspect every API response body — do not rely on what the UI shows. Automated tooling that diffs response schemas against documented API specs helps surface undocumented fields at scale.

Mass assignment is the write-side analogue. When an API automatically maps request body properties onto internal model objects, a client can inject properties the server never intended to accept. The classic example: a PUT /api/users/me endpoint meant to update a display name might also accept { "role": "admin", "verified": true, "credit_balance": 9999 }. Test by adding extra fields to every POST/PUT/PATCH body — particularly fields observed in GET responses for the same resource.

Rate Limiting, Resource Exhaustion, and SSRF via APIs

Absent or easily bypassable rate limiting on sensitive endpoints creates real business risk. Password reset flows, OTP verification endpoints, and login routes that accept unlimited requests are exploitable for brute force. Test rate limiting by sending requests in rapid succession and watching for 429 responses. If limits exist, attempt bypass using X-Forwarded-For header rotation, distributing requests across IP addresses, or slightly varying the payload to defeat simple deduplication.

SSRF vulnerabilities frequently appear in APIs that accept URLs or hostnames as input — webhook registration endpoints, URL preview features, document importers, and integration connectors. Supply internal addresses: http://169.254.169.254/latest/meta-data/ for AWS metadata, http://localhost:6379/ for Redis, or http://internal-service.corp/admin. Even blind SSRF — where you cannot read the response — can be detected by monitoring for outbound DNS queries or HTTP requests to a collaborator server.

GraphQL-Specific Attack Techniques

GraphQL introduces a different threat model compared to REST. The first thing to check on any GraphQL endpoint is whether introspection is enabled in production. A successful __schema query reveals every type, field, mutation, and subscription the API exposes — a complete map of the attack surface handed to an attacker for free. Introspection should be disabled in production, but many deployments leave it on. If introspection is disabled, field suggestions often remain active and reveal valid field names through error messages like "Did you mean `password`?" — use tools like Clairvoyance to enumerate the schema through suggestions.

Query batching and aliasing are powerful for bypassing rate limits. GraphQL allows sending an array of operations in a single HTTP request. An OTP brute-force attack that would trigger rate limiting with 1000 individual requests can be condensed into a single request containing 1000 aliased mutations: a1: verifyOtp(code: "0000") { token } a2: verifyOtp(code: "0001") { token } and so on. Many rate limiting implementations operate at the HTTP request level, not the GraphQL operation level, making this a reliable bypass.

Deeply nested queries exploit the recursive nature of GraphQL schemas to cause denial-of-service conditions. If a User type has a friends field that returns a list of User objects, each of which has a friends field, a query can nest dozens of levels deep and cause exponential backend computation. Production GraphQL deployments should enforce query depth limits, query complexity scoring, and field-level rate limiting — test for all three. Also test for broken authorization at the field level: even if the top-level query is authorized, individual fields within the response may return data belonging to other users if resolvers do not independently enforce authorization.

Building an Effective API Testing Workflow

Effective API testing starts with thorough enumeration before attacking. Collect OpenAPI/Swagger specs, postman collections, JavaScript bundles (which often contain API paths hardcoded in client code), and mobile app binaries. Use tools like kiterunner to brute-force undocumented endpoints against common API path wordlists — you will regularly find admin endpoints, debug routes, and deprecated API versions that are not in any official documentation.

Instrument your testing to capture the full request/response cycle. Burp Suite Pro with a custom match-and-replace for authorization headers makes testing multiple user roles manageable. For automated regression testing, write API test suites that run in CI/CD pipelines and fail the build if BOLA or excessive data exposure is detected. Tools like OWASP ZAP with API-mode scanning, or Nuclei with community-maintained API templates, can cover common vulnerability classes at scale.

Document every finding with a proof-of-concept that demonstrates real impact, not just technical existence. For BOLA, show the exact request that returns another user's data. For mass assignment, show the exact field that was accepted and the resulting change in the database. API security vulnerabilities are often dismissed by development teams as theoretical — concrete reproduction steps and demonstrated impact are what turn findings into remediated code.

Stop finding vulnerabilities manually

TigerStrike uses AI agents to continuously discover, validate, and exploit vulnerabilities across your applications — so your team can focus on fixing what matters.