AI Pentesting

What is API Penetration Testing: How It Works and Why It Matters

Amartya | CodeAnt AI Code Review Platform
Sonali Sood

Founding GTM, CodeAnt AI

Most modern applications are APIs with a thin interface on top. That is also where most modern breaches happen, because APIs expose business logic and data directly, and a flaw in one endpoint can leak an entire database.

API penetration testing is how you find those flaws before an attacker does. This guide covers what it is, the vulnerabilities that matter most, how the testing actually works, and why testing that understands your code finds what external scanners miss.

What CodeAnt AI solves here: CodeAnt AI runs code-aware API testing that reads your source, so it knows every endpoint that exists, which middleware guards it, and where user input flows. It proves exploitable API flaws with a working proof of concept, not a list of maybes. It also one of those vendors offering 48-hour delivery.

What is API Penetration Testing?

API penetration testing is the practice of attacking an application's APIs the way a real adversary would, to find and prove exploitable flaws. It targets the endpoints behind the interface, across REST, GraphQL, and gRPC, not only the pages a user clicks.

It sits inside the broader category of API security testing, which also includes automated scanning and posture checks. The penetration testing part is the deeper, exploit-driven layer that proves which flaws are actually reachable.

The distinction matters because APIs fail differently from web pages. The vulnerabilities are less about classic injection and more about authorization, which is exactly the class of bug that needs context to find.

REST, GraphQL, and gRPC each expose this differently.

A REST API leaks it through the URL path or query string — GET /api/v1/orders/1042 is a direct object reference.

GraphQL leaks it through resolver arguments buried inside a single POST body — query { order(id: 1042) { total, customerEmail } } — which means the object-reference problem is identical, but a tool that only inspects URLs never sees it, and introspection (__schema) can hand an attacker the entire object graph before they even start.

gRPC leaks it through message fields in a binary protobuf payload, so enumeration means decoding the .proto definition (or the service reflection API, when enabled) to find which fields map to object IDs.

The rest of this guide walks through REST examples because they're easiest to show inline, but the same authorization logic — and the same BOLA/BOPLA/BFLA categories — applies across all three; see the GraphQL penetration testing checklist for the query-shaped version of these attacks.

Why APIs Need Their Own Penetration Testing

Testing an API is not the same as testing a website. A web page hides functionality in the interface, but an API exposes every operation directly, so anything the server does not enforce is reachable by anyone who knows the endpoint.

The scale of the surface is the problem. A single application can have hundreds of endpoints, many undocumented, each accepting parameters that map to database records. Miss one authorization check and an attacker can enumerate data across every user.

This is why API-first and microservices architectures need dedicated testing. Lateral movement between services is defined in code, and authorization gaps between an API gateway and a downstream service are invisible from the outside.

Our guide on how AI penetration testing works walks through a real chain that starts at an exposed API.

The Most Common API Vulnerabilities

The OWASP API Security Top 10 captures the patterns that matter. A few dominate real breaches.

Vulnerability

What it is

Why it is dangerous

Broken object level authorization (BOLA/IDOR)

An endpoint returns a record without checking the requester owns it

Enables enumeration of every user's data

Broken authentication

Weak or missing token validation

Full account takeover

Excessive data exposure

The API returns more fields than the UI shows

Leaks sensitive data the client filters out

Broken function level authorization

Admin endpoints with no server-side role check

Privilege escalation to admin actions

Missing rate limiting

No limit on requests per parameter

Enables brute force and mass extraction

Broken object level authorization is the standout. It is the single most common and most damaging API flaw, and in multi-tenant SaaS it can expose one customer's data to another when the query trusts a client-supplied tenant ID instead of enforcing it server-side.

What BOLA looks like on the wire. A logged-in low-privilege user requesting their own order returns data as expected:

GET /api/v1/orders/1042 HTTP/1.1
Authorization: Bearer <user_A_token>

GET /api/v1/orders/1042 HTTP/1.1
Authorization: Bearer <user_A_token>

GET /api/v1/orders/1042 HTTP/1.1
Authorization: Bearer <user_A_token>

Change nothing but the object ID, keeping the same low-privilege token:

GET /api/v1/orders/1043 HTTP/1.1
Authorization: Bearer <user_A_token>

GET /api/v1/orders/1043 HTTP/1.1
Authorization: Bearer <user_A_token>

GET /api/v1/orders/1043 HTTP/1.1
Authorization: Bearer <user_A_token>

If the server checks that the requested resource belongs to the caller, this returns 403. If it only checks that the caller is authenticated at all, which is a much more common mistake, it returns 200 with someone else's data, and an attacker can enumerate every order in the system by incrementing an integer.

That gap between "is this caller logged in" and "does this caller own this specific object" is the entire BOLA category, and it's what every row of the findings table below turns out to be.

What These API Vulnerabilities Look Like in Real Code

The categories above stay abstract until you find them in shipped software. In 2026 CodeAnt's security research ran a single API penetration test against Dolibarr, an open-source ERP with hundreds of REST endpoints, and reported nine findings across the full Dolibarr write-up.

Eight of the nine are API bugs, and they collapse into three OWASP categories. The clustering is the point. The same two or three authorization failures repeat across all eight, which is why they read as one story rather than eight separate bugs.

Finding

OWASP API category

What one low-privilege API key achieved

Read the analysis

Portal takeover

API1:2023 Broken Object Level Authorization

Rewrote another company's portal login and took over the account

CVE-2026-71505

Payment redirection

API1:2023 Broken Object Level Authorization

Changed a supplier's bank IBAN so future payments route to the attacker

CVE-2026-71507

Members takeover

API3:2023 Broken Object Property Level Authorization

Reset a linked user's password through a field the form never exposes, reaching admin

CVE-2026-71504

Payroll tampering

API3:2023 Broken Object Property Level Authorization

Set its own salary through the Users API while holding no payroll permission

CVE-2026-71508

Hash disclosure

API3:2023 Broken Object Property Level Authorization

Read every member's live bcrypt password hash from a read-only endpoint

CVE-2026-71511

Filter oracle

API3:2023 Broken Object Property Level Authorization

Extracted salaries and a password hash one bit at a time through a search filter

CVE-2026-71510

Payment deletion

API5:2023 Broken Function Level Authorization

Deleted posted payments using a permission meant for a different action

CVE-2026-71506

Self-approval

API5:2023 Broken Function Level Authorization

Filed an expense claim and approved it, and its whole team's, with only the filer right

CVE-2026-71509

Admin account takeover

Reflected XSS (CWE-79), not an API authorization category

A single link opened by an admin creates a second admin account with an attacker-chosen password and REST API key

CVE-2026-71503

The ninth finding, the admin takeover above, is the odd one out in the set: it's a reflected XSS rather than an authorization gap, but it earns its place because the same "safe path exists, this call site skips it" pattern shows up again. An output-encoding function already existed in the codebase; it just wasn't used at the vulnerable template.

Full breakdown in CVE-2026-71503.

How these get scored. Not every authorization gap carries the same severity, and CVSS is the common baseline for prioritizing a findings list.

The scoring leans heavily on impact and required privilege: the portal takeover and payment redirection findings above both score in the critical range under CVSS 3.1 because they need only a low-privilege, unauthenticated-adjacent API key and result in full account or financial compromise, with Attack Vector: Network, Attack Complexity: Low, Privileges Required: Low, and Confidentiality/Integrity Impact: High.

The hash disclosure and filter oracle score slightly lower on their own (high confidentiality impact, but no direct integrity impact), at least until you account for chaining (see below).

The admin takeover finding scores highest of the set at CVSS 9.3, since a single link opened by a legitimate administrator is enough to reach full account creation with attacker-chosen credentials, no direct API access required to trigger it.

API1:2023 Broken Object Level Authorization (BOLA)

BOLA, still widely called IDOR or insecure direct object reference, is an endpoint returning or changing a record without confirming the caller owns it. It is the most common and most damaging API flaw, and it is where enumeration attacks live.

Two of the Dolibarr findings are pure BOLA. The portal takeover let a member of one company rewrite the portal credentials of another, and the payment redirection let a caller change a third party's bank account so payment files pointed at the attacker.

To test for it, authenticate as a low-privilege user and request or modify objects that belong to another account by changing the id in the path or body. A missing ownership check answers 200 where it should answer 403.

API3:2023 Broken Object Property Level Authorization (BOPLA)

BOPLA merges the older mass assignment and excessive data exposure categories. It is about individual fields rather than whole objects, and it runs in both directions.

Writing a field you should not be able to set is mass assignment. The members takeover wrote a linked user's password to reach admin, and the payroll tampering wrote a salary through the Users API with no payroll right. A mass assignment payload is usually as simple as adding one extra key to a legitimate request body:

PATCH /api/v1/users/318 HTTP/1.1
Authorization: Bearer <user_token>

PATCH /api/v1/users/318 HTTP/1.1
Authorization: Bearer <user_token>

PATCH /api/v1/users/318 HTTP/1.1
Authorization: Bearer <user_token>

If the handler blindly maps the request body onto the model instead of allow-listing which fields a given role may write, role persists even though no part of the UI ever exposes it. This is the same class of bug behind the payroll tampering finding, see the full breakdown of that mass assignment chain in the Dolibarr findings post for the exact field and endpoint.

Reading a field the endpoint should hide is excessive data exposure. The hash disclosure returned a live password hash to a read-only key, and the filter oracle leaked hidden columns one bit at a time.

To test for it, add fields to the request body that the interface never sends, such as role, salary, status, or is_admin, and check whether they persist. On the read side, compare the raw API response to what the UI renders and look for fields that should have been stripped.

API5:2023 Broken Function Level Authorization (BFLA)

BFLA is reaching a function the caller's role should not allow. It usually appears when a second route to the same action skips the permission check the primary route enforces.

The Dolibarr set shows the pattern twice. The payment deletion checked a permission for the wrong action and let a low-privilege user delete posted payments, and the self-approval let a generic update route write the approval fields that a dedicated approve route was guarding.

To test for it, enumerate every route that reaches a privileged action rather than only the obvious one, and confirm each checks the function-level permission. State-changing fields exposed on a generic update endpoint are a frequent gap.

A pattern this consistent is hard to catch from the outside, because every request in it is authenticated and well-formed. Finding it means reading which routes reach which fields and which permission each one actually checks, which is the code-aware angle the rest of this guide covers.

How API Penetration Testing Works

A thorough API test follows the same disciplined process as any pentest, focused on the endpoints.

  1. Endpoint enumeration. Discovering every route including undocumented and debug endpoints. In practice this means diffing the routes an API gateway or reverse proxy actually serves against what's in the public API spec — a /api/v1/internal/export route with no corresponding OpenAPI entry is exactly the kind of endpoint that never gets reviewed and is often the least protected.

  2. Authentication testing. Checking token validation, session handling, and algorithm confusion. Concretely: does the API accept a JWT signed with alg: none? Does it verify the signature against the expected key, or trust whatever kid the token claims? Does an expired or logged-out token still get accepted on replay? Each of these is a one-request test once you have a valid token to modify.

  3. Authorization testing, the core of API testing. Confirming each endpoint enforces object and function level access — this is the BOLA/BOPLA/BFLA testing shown above, run systematically across every enumerated endpoint rather than spot-checked on a few.

  4. Injection and logic testing. Probing for injection sinks and business logic abuse — for example, submitting a negative quantity to a /cart/add endpoint to see if it credits the account instead of charging it, or reordering a multi-step workflow's calls to skip a validation step the UI normally enforces in sequence.

  5. Chaining. Combining findings into an attack path that reaches real data. This is where a single low-severity finding stops being low severity: the hash disclosure and filter oracle findings above are each moderate in isolation, but chained together — leak a hash, then use the oracle to recover another user's session details — the combination reaches a full account compromise a CVSS score computed per-finding won't show on its own.

  6. Proof and reporting. Delivering a working proof of concept and remediation for each finding, scored and prioritized so the highest-impact, lowest-effort-to-exploit issues surface first.

The authorization phase is where API testing earns its value. Confirming that every endpoint checks ownership at the data layer, not just the API layer, is what catches the BOLA and IDOR flaws that cause the biggest breaches.

Why Code-Aware Pentesting Finds API Flaws External Scanners Miss

External-only tools observe API traffic and guess at behavior. They fuzz parameters without knowing which endpoints exist, what each one touches, or where authorization is supposed to happen.

Code-aware testing inverts that. By reading the source, it enumerates every route directly, traces which endpoints accept user-controlled IDs without checking ownership, and follows data flow from the endpoint to the database. That is how it finds the authorization gap that an external scanner walks right past.

The difference shows up most in a BOLA hunt. Instead of blindly fuzzing IDs across endpoints, code-aware testing identifies the exact subset of endpoints where the code never validates ownership, then proves the exploit. This is the same gray box approach that pairs outside attack with inside knowledge.

How CodeAnt Runs API Penetration Testing

CodeAnt tests APIs with full code context, continuously. It reads your codebase to map every REST, GraphQL, and gRPC endpoint, understands the authentication and authorization logic, and attacks each endpoint from the outside using that knowledge.

Findings come back as proof, not guesses. You get the vulnerable endpoint, the exact code path, a working proof of concept, and a remediation, with a retest to confirm the fix. Because testing runs on every change, new endpoints get validated as they ship rather than at the next annual engagement.

This is exactly how the Dolibarr findings were surfaced: CodeAnt's code-aware engine mapped the Users API and traced which fields a request body could write, which is what caught the payroll tampering finding: a salary field the UI never exposed but the handler still accepted from any authenticated caller.

An external scanner fuzzing that same endpoint from the outside would need to guess the exact undocumented field name; reading the source finds it directly. You can see the offensive side on the pentesting page or explore the vulnerability database behind it.

The Bottom Line on API Penetration Testing

APIs are where your business logic and your data live, which makes them where attackers focus. API penetration testing finds the authorization and logic flaws that cause the largest breaches, and broken object level authorization sits at the top of that list.

The flaws that matter most need context to find, since they live in authorization logic the interface hides but the API exposes. Testing that reads your code finds them with precision, proves them with a working exploit, and retests the fix, which is what separates a real API pentest from a scanner run.

That is the model CodeAnt runs. Ready to see what an attacker could reach through your APIs? Launch a free black box scan for one URL, then book a walkthrough to see code-aware API testing against your own stack.

FAQs

What is API penetration testing?

How do you test the security of an API?

What is the difference between API security testing and API penetration testing?

What are the most common API vulnerabilities?

How much does API penetration testing cost?

Start Your 14-Day Free Trial

AI code reviews, security and quality trusted by modern engineering teams.

Table of Content
No headings found on page
Ship clean & secure code faster

Get Pentest Report

NO CC REQUIRED