Loading...
Loading...
API security testing checks whether an API enforces authentication, authorization, input validation, and rate limits when callers break the rules on purpose. Authorization is where the risk sits: in Salt Labs' H2 2026 State of AI and API Security report, 95.8% of API attack attempts came from authenticated sources. Catching those failures means requesting every endpoint as every role.
Log in as two customers. Copy an invoice ID from the first, request it as the second, and watch for a 200 OK.
That swap, asking for someone else's record, is the whole exploit behind the U.S. Postal Service API flaw that KrebsOnSecurity reported in 2018. Any logged-in usps.com user could look up account details for some 60 million others. A researcher had reported it more than a year before it was fixed.
One swap is easy. Every endpoint, method, role, and tenant adds another cell, though, and a time-boxed test only samples a few of them by risk. Fill in the whole grid, and the OWASP API Top 10 and more than a decade of public API incidents both land on it.
API security testing is the practice of attacking a REST, GraphQL, or SOAP API the way an adversary would, to find out who it lets in and what it lets them reach. Functional API testing checks that a legitimate caller gets the right answer.
Security testing asks what happens when the caller is the wrong user, or sends requests in an order nobody designed for.
API security is the set of controls that decide who an API answers and with what: authentication, authorization, input validation, and rate limits. Testing proves those controls hold.
The reference list is the OWASP API Security Top 10, last revised in 2023. It names the ten most critical API security risks, and three of its top five are authorization failures. A fourth is broken authentication. So most of your testing hours belong on authorization.
API penetration testing (API pentesting) is a hands-on attack on an API, run with real authenticated sessions across roles and tenants, that proves each flaw with request-and-response evidence. An API security scanner flags single responses; a pentester chains requests to show what an attacker can actually reach.
API penetration testing also differs from web application testing in where it starts. It skips the pages and forms a web app pentest drives and calls routes directly, including ones no screen ever requests.
Most automated API security testing misses broken object level authorization (BOLA, also called IDOR) because one identity can't see it. Spotting it takes a second identity, an object that identity doesn't own, and a policy that says who should see it.
A request from user B for user A's invoice is syntactically perfect. Valid token, real route, 200 OK, and a single-session scan records a pass.
An API security scanner logged in as one user can't ask whether a second user reaches the same object. That's why OWASP's Web Security Testing Guide (WSTG-APIT-02) tells testers to "utilize two different accounts." It treats a 200 OK for another user's object as the indicator.
Even with two sessions, nothing in the response says whether the caller was supposed to see it. There's no policy oracle. Cloudflare's API security team calls this a chicken-and-egg problem. If you already knew the correct permission structure, or could guarantee its enforcement, the attack wouldn't have worked in the first place.
You also need something to steal: a real object, owned by someone else, in the right state. Random fuzz values fail validation long before they reach the authorization check.
Burp Suite's Autorize and AuthMatrix extensions and ZAP's access control add-on test for BOLA and IDOR by replaying each request under several sessions and diffing the responses. Seeding the objects, defining the expected answer for each cell, and keeping both current every release is the part they leave to you.
Swapping sequential IDs for UUIDs, or encrypting them client-side, makes IDs harder to guess and changes nothing about who the server returns them to. The fix is a server-side ownership check on every request and every method. For behavior flaws beyond authorization, see the guide to business logic vulnerabilities.
To test API security for authorization, fill a grid of every endpoint, method, role, and tenant with an expected answer in each cell. Then request each seeded object as every other principal and compare what came back with what should have. That grid is what an API penetration test for access control has to cover.
The table below is a slice of that grid for a fictional B2B invoicing API, with three test identities. Two sit in tenant Acme (a Member and an Admin), and one is an Admin in tenant Globex. Every request targets invoice 1042 or user 77, both owned by Acme. The user record is the Acme Member's own profile.
| Request (target owned by Acme) | Acme Member | Acme Admin | Globex Admin |
|---|---|---|---|
GET /invoices/1042 |
OK: allowed | OK: allowed | OK: denied (403) |
PATCH /invoices/1042 |
FAIL: expected deny, got 200 (BFLA) | OK: allowed | OK: denied |
DELETE /invoices/1042 |
OK: denied | OK: allowed | OK: denied |
GET /invoices/1042/pdf |
OK: allowed | OK: allowed | FAIL: expected deny, got 200 (BOLA) |
POST /invoices/1042/share |
OK: denied | OK: allowed | OK: denied |
PATCH /users/77 with "role": "admin" |
FAIL: role change saved (BOPLA) | OK: allowed | OK: denied |
Eighteen cells, three findings. Each sits where these bugs like to hide. The export route skipped the tenant ownership check its parent route runs. The write method skipped the admin-only check its sibling DELETE enforces. And the profile update bound every field in the request body, a textbook mass assignment vulnerability.
Now scale it. A product API with 120 endpoints, 2.5 methods each, four roles, and two tenants has 2,400 cells (120 × 2.5 × 4 × 2). Each one needs a seeded object in the right state and a live session per identity.
The next release adds eight endpoints and a role. The grid changes again.
A human tester samples it by risk, usually starting from the cells someone thought to write down. A single-identity scanner can't run it at all.
Four rules keep the grid complete as it grows.
DELETE is the method teams forget.You test each OWASP API Security Top 10 risk by sending the request that would exploit it and capturing the response that proves it: another principal's object returned, a protected field saved, or a request accepted without credentials. The 2023 edition of the OWASP API Top 10 is still the current one.
That edition merged 2019's Excessive Data Exposure and Mass Assignment into API3, Broken Object Property Level Authorization.
| OWASP API 2023 | What you test | What proves it |
|---|---|---|
| API1 Broken Object Level Authorization | Objects owned by another user or tenant, on every method | Another principal's object returned or changed |
| API2 Broken Authentication | Unauthenticated routes, token signing and expiry, login and reset flows | A request accepted with no, expired, or forged credentials |
| API3 Broken Object Property Level Authorization | Fields returned beyond what the role needs; fields the role should not be able to set (role, price, owner) | A sensitive field returned, or a protected field saved |
| API4 Unrestricted Resource Consumption | Page, batch, and upload sizes; cost of expensive operations | One caller drives unbounded responses, cost, or latency |
| API5 Broken Function Level Authorization | Admin and privileged functions called by lower roles | A lower role runs a privileged function |
| API6 Unrestricted Access to Sensitive Business Flows | Automation of signup, checkout, booking, and lookup flows | A flow abused at a volume the business would not accept |
| API7 Server Side Request Forgery | Any parameter that makes the server fetch a URL | The server fetches a destination the caller chose |
| API8 Security Misconfiguration | CORS, verbose errors, unneeded methods, debug endpoints | An exposure that needs no code flaw |
| API9 Improper Inventory Management | Old versions, undocumented hosts, staging endpoints | A live endpoint missing from inventory, or v1 weaker than v2 |
| API10 Unsafe Consumption of APIs | How the API treats responses from third-party APIs it calls | Third-party data processed without validation |
OWASP left injection off the list because, in its words, such risks "don't behave differently in APIs." Keep the injection checks you'd run on any web application.
Most API vulnerabilities behind public incidents are authorization and authentication flaws. Of eight documented cases, four trace to BOLA or broken authentication, two to property-level authorization, one to a lookup abused at volume, and one to an API that served data without authorization. All eight are publicly documented, and each maps to one repeatable test.
| Incident | What the public record says | OWASP 2023 | The test that catches it |
|---|---|---|---|
| USPS Informed Visibility (2018) | Any logged-in usps.com user could query account details of other users, about 60 million accounts (KrebsOnSecurity) | API1 | Request another account's record as a second logged-in user |
| McDonald's McHire / Paradox.ai (2025) | Default credentials on a test admin account plus an IDOR on an internal API made data on more than 64 million applicants retrievable (Ian Carroll and Sam Curry) | API1, API8 | Change the object ID as a user from another tenant; check for default credentials |
| Spoutible (2024) | A profile API returned other users' email, IP address, password hash, 2FA secret, and reset token; 207,000 records were scraped (Troy Hunt) | API3 | Compare every response field with what the requesting role needs |
| GitHub (2012) | A form failed to check incoming parameters, a mass assignment vulnerability that let a user add his key to the rails organization; fixed about an hour after the attack (GitHub) | API3 | Send protected fields in write requests and check what was saved |
| T-Mobile (2023) | A bad actor was "obtaining data through a single Application Programming Interface" without authorization, from about 37 million accounts (T-Mobile SEC filing) | Authorization (class not named in the filing) | Map each data-returning API to its intended callers, then call it as everyone else |
| Twilio Authy (2024) | An unauthenticated endpoint let threat actors identify data tied to Authy accounts, including phone numbers (Twilio) | API2 | Call every endpoint with no credentials at all |
| Trello (2024) | An actor ran a pre-existing email list against an API that returned public profiles by email, without authentication; the lookup worked as designed, and Atlassian then restricted it (Atlassian) | API6 | Test account-lookup flows with no session and at volume |
| Peloton (2021) | Unauthenticated endpoints, including a GraphQL gateway, returned user data even for profiles set to private (Pen Test Partners) | API1, API2 | Request a private profile as a stranger and as nobody |
Only USPS and McHire needed a second identity to catch. Authy and Peloton answered requests with no credentials of any kind, which a routine unauthenticated scan sends.
That cuts against this post's own title.
Trello's lookup needed no session either, and it worked as designed, so only a test at volume flags it.
GraphQL pentesting means testing authorization on every resolver, field, and nested edge with several identities, then checking batching against rate limits, query depth and cost, and schema exposure. One endpoint, usually /graphql, carries every operation. A route-based scan sees one URL and runs one set of tests.
GraphQL leaves authorization to your resolvers, and nested edges are where it slips. A query for invoice(id: 1042) can be denied while me { organization { invoices { id total } } } returns the same rows. That's why OWASP's GraphQL cheat sheet says to enforce authorization "on both edges and nodes."
One HTTP request can carry many operations through batching or aliases, so a rate limiter that counts requests sees one call while the server runs hundreds. OWASP warns these attacks "will likely bypass existing rate limits." Nesting is unbounded by default too, so test for a depth limit, an amount limit, or query cost analysis.
Disabling introspection in production is sensible, but field suggestions and the client's own JavaScript bundles reveal operations anyway, so test authorization as if the attacker already has the schema.
An API pentest finding should prove which identity made the request, which object it reached, the exact request and response, and how to reproduce it. "Possible IDOR on /invoices" is a hypothesis. A good finding lets a developer reproduce, fix, and retest it without asking the tester anything.
Here's the finding from the matrix above:
| Field | Example |
|---|---|
| Finding | BOLA on GET /invoices/{id}/pdf |
| Identities | Requester: Globex Admin. Owner: tenant Acme |
| Object | Invoice 1042, owned by tenant Acme |
| Request and response | Globex Admin token, GET /invoices/1042/pdf, returned 200 with Acme's invoice PDF (body redacted) |
| Reachable scope | Every invoice ID in sequence, across tenants (inferred from sequential IDs; confirmed on 1042) |
| Root cause | The export route skips the tenant ownership check its parent route runs |
| Fix | One ownership check in shared middleware for every invoice route |
| Retest | Same request, same identities, after the fix: expect 403 |
Reachable scope and the retest matter more than the severity score. Reachable scope is the blast radius, and a per-request score tends to understate it for BOLA, where one flaw can expose every object of a type. The retest has to repeat the same request under the same identities.
A looser retest can pass a fix that only moved the missing check to a sibling route. The durable fix is a regression test for each confirmed finding, run on every build in your CI/CD pipeline.
Yes, AI agents can run the authorization part of API penetration testing on the APIs behind your web applications. An agent holding several authenticated identities at once can test every endpoint-by-role cell on demand or on a continuous schedule, which is more hours than most teams can give it by hand.
An agent can't read a contract. Business rules that live only in an agreement or a support ticket need a pentester who knows the business. That pentester's week shifts toward reviewing agent findings and writing the business-rule tests no agent can infer.
Simbian's AI Pentest Agent works this way. You give one pentest several authenticated roles, and it runs a parallel attacker per role, then cross-checks what each one reached. Each test is one endpoint, HTTP method, vulnerability class, and user role, much like a cell in the grid above. The highest-privilege role you supply sets the baseline the lower roles are tested against.
Every finding comes with a Thought Trace (the agent's reasoning trail), deterministic reproduction steps, and the HTTP request and response behind it. That's the evidence a finding like the one above needs.
Proving a write-method flaw can mean changing real data. Scope is enforced outside the model, and Safe mode puts a second model in front of every candidate exploit, checking it for exfiltration and disruption risk and vetoing high-risk actions before any attacker runs them.
When a pentester corrects a finding, the edit is versioned with the reason, and the next retest reasons with that correction.
Self-improving, not self-driving.
The matrix proves the export route leaks. Whether anyone would notice someone using it tomorrow is a SOC question, and because the pentest and the AI SOC Agent run on one platform, a proven path also becomes a detection check.
Q: How do you test API security? Build an inventory of every endpoint, method, and role from the spec and live traffic. Then call each route with no token, an expired token, and every role's token; swap object IDs between two users and two tenants; send protected fields in write requests; and probe rate limits. Any response that differs from the intended access policy is a finding.
Q: What is the difference between API testing and API security testing? API testing checks that an API works for a legitimate caller: correct responses and status codes. API security testing checks what happens when the caller is unauthorized, holds the wrong role, or sends inputs and sequences the designers never intended. An API can pass every functional test while handing one customer's data to another.
Q: How often should you run API security testing? Run authorization tests whenever a release adds an endpoint or changes the permission model, because that's when the matrix changes. An annual pentest satisfies most compliance calendars, but an API that ships weekly can carry a new BOLA flaw for most of a year before the next annual test finds it.
Q: Can you do API security testing without an OpenAPI spec? Yes, but start by building an API inventory from gateway logs, proxy traffic, and the client's JavaScript. Specs drift. In its 2024 API security report, Cloudflare found 30.7% more API endpoints through machine-learning discovery of live traffic than its customers had identified themselves. The endpoint missing from the spec is usually the one nobody tested.
Q: How do you automate API security testing in CI/CD? Turn each confirmed finding into a regression test that replays the same request under the same identities on every build, and fail the build when a cell that should deny returns 200. Add an unauthenticated pass over every route and a spec-driven scan such as ZAP's API scan. Re-seed test objects each run so denials stay meaningful.
Q: Does PCI DSS require API penetration testing? Indirectly, yes. PCI DSS v4.0.1 requirement 11.4.1 calls for application-layer penetration testing covering the vulnerabilities listed in requirement 6.2.4. That list names attacks that manipulate APIs to abuse business logic, and attacks on authorization mechanisms. An API inside your cardholder data environment's scope needs that testing.
Q: Does using UUIDs instead of sequential IDs fix BOLA? No. Non-sequential identifiers make enumeration harder, and OWASP lists them as a supporting control, but any UUID that leaks through a shared link or another API response is still served to whoever requests it. Only a server-side check on every request and method closes it.
Q: What are the best API security testing tools? The standard API security testing tools, also used for API penetration testing, are Burp Suite with an authorization extension such as Autorize, ZAP's API scan for OpenAPI, SOAP, and GraphQL definitions, and Postman for scripted request collections. For GraphQL, add InQL or graphql-cop. They send, replay, or generate requests. Deciding which response breaks the access policy is the tester's job.
Q: How do you prepare an API for a penetration test? Before API pentesting starts, provide the OpenAPI or GraphQL schema and a test environment with production-like data. Add at least two accounts per role in two separate tenants, so testers can swap object IDs between owners. Testing with credentials and a spec is grey-box; adding source code makes it white-box; starting from only the URL is black-box.
Draw your own matrix before the next release.
Count the cells, mark the ones your testing actually exercises, and the unmarked cells are what you're shipping untested. To see an authorization finding with its request, response, and Thought Trace, book a demo.