Quassr CyberTech | Logo
About Us
Capabilities
Case Studies
Platforms & Ecosystem
Industries
Blogs
Careers
Contact Us
Home/Blogs/Article
Cyber Security

API Pentesting Beyond the OWASP API Top 10

Real-world API security testing goes beyond ten predefined categories - exploring BOLA, mass assignment, rate-limit bypasses, GraphQL abuse, and shadow endpoints.

API Pentesting Beyond the OWASP API Top 10
QuassrCyberTech06/10/2026 · 15 min readCyber Security

Introduction

APIs have become the connective tissue of modern applications. Banking applications use APIs to transfer funds, retrieve account information, and manage beneficiaries. SaaS platforms rely on APIs for tenant management, billing, file sharing, and administrative functions. Fintech applications expose APIs for payments, KYC, wallets, transactions, and customer onboarding.

That central role has also made APIs an attractive target.

The OWASP API Security Top 10 provides an important foundation for identifying common API security weaknesses, but real-world API penetration testing rarely ends with checking ten predefined categories. The most damaging findings often emerge when testers examine how authorization, object references, business functions, API versions, GraphQL schemas, rate limits, and undocumented endpoints interact.

A seemingly secure API may enforce authentication correctly while still allowing one customer to access another customer's invoice. An administrative endpoint may be protected by authentication but fail to verify whether the authenticated user is actually authorized to perform the operation. A mobile application's JSON request may accept fields that were never intended to be controlled by the user. An older API version may remain online long after the development team has stopped maintaining it.

These weaknesses are often less about a single vulnerable parameter and more about trust assumptions between the client, API gateway, application logic, and backend services.

This post explores the areas that API penetration testers should investigate beyond simply mapping findings to the OWASP API Top 10.


Why the OWASP API Top 10 is Only the Starting Point

Markdown image

The OWASP API Security Top 10 provides a useful framework for identifying recurring API security problems. However, penetration testing is not simply a checklist exercise.

A tester may identify an endpoint such as:

GET /api/v1/accounts/12345
Authorization: Bearer {token}

Even when authentication, input validation, and transport encryption all pass, the endpoint may still expose another customer's account if the application determines access solely from the supplied account ID.

This is where API security testing moves from asking whether an endpoint works to asking who is allowed to make it work, against which object, and under what circumstances. A useful test therefore examines several dimensions simultaneously - who is making the request, what object they are accessing, what operation they are performing, which fields they can control, how frequently they can act, which API version they are on, and whether undocumented services are reachable. The answers often reveal vulnerabilities that are invisible when testing endpoints in isolation.


BOLA / IDOR: When the Object ID Becomes the Authorization Boundary

Broken Object Level Authorization, commonly associated with IDOR-style vulnerabilities, remains one of the most important API security problems. The vulnerability occurs when an API accepts a reference to an object but fails to verify that the authenticated user is authorized to access that specific object.

Consider a fintech application:

GET /api/v1/transactions/845721
Authorization: Bearer USER_A_TOKEN

The application correctly authenticates the user. However, if changing the identifier to:

GET /api/v1/transactions/845722
Authorization: Bearer USER_A_TOKEN

returns a transaction belonging to another customer, the authorization boundary is broken.

The issue is not necessarily that the identifier is predictable. Even UUID-based identifiers can be exposed through other application functionality, logs, exports, browser history, or API responses. The important question is whether the server verifies ownership or authorization for the referenced object.

Banking Example

Imagine a banking application where a customer can download monthly statements:

GET /api/v2/statements/8c9f1a21/download
Authorization: Bearer {customer-token}

A tester obtains a statement identifier belonging to another account and submits the request using their own session. If the server returns the other customer's PDF, the application has an object-level authorization failure.

In banking and fintech applications, object identifiers frequently appear outside the primary request path. Statement IDs have been found in PDF filenames returned by Content-Disposition headers, in webhook payloads sent to merchant callbacks, and embedded in JWT claims when a user switches accounts. A tester who only enumerates path parameters is examining a fraction of the object reference surface.

The same problem surfaces across any object the application manages - statements, beneficiary records, loan documents, KYC files, investment portfolios - wherever the server accepts an identifier without verifying ownership. The identifier itself is not the vulnerability. The missing authorization decision is.

Markdown image

Broken Function-Level Authorization: Authentication Does Not Mean Permission

Object-level authorization asks whether a user can access a particular object, while function-level authorization asks whether that user is permitted to perform a particular operation.

Consider a SaaS application with these endpoints:

GET /api/users/profile
POST /api/users/profile
POST /api/admin/users
DELETE /api/admin/users/123

A standard employee may legitimately access the first two endpoints. The security boundary breaks if that same employee can successfully invoke:

POST /api/admin/users

simply because the endpoint is accessible and the application validates only that a valid session exists.

A common testing mistake is to verify that administrative pages are hidden from normal users and assume the underlying functionality is protected. APIs can tell a different story. A frontend may hide a "Delete User" button from a standard employee - but the backend endpoint may still exist and accept requests from anyone with a valid session.

SaaS Example

Consider a multi-tenant project-management platform in which an administrator can invoke:

POST /api/v1/tenants/users/remove

A normal user should not be able to call this function. However, if the API only checks whether the requester is authenticated rather than confirming that the requester has the administrator role and belongs to the authorized tenant, the endpoint becomes a function-level authorization vulnerability.

The impact becomes serious when those functions include user creation and deletion, role changes, billing modifications, API key generation, SSO configuration, or data exports - operations that can affect entire tenants, not just individual accounts.


Mass Assignment: When the Client Controls More Than It Should

Mass assignment occurs when applications automatically bind user-controlled request fields to internal objects without sufficiently restricting which properties can be modified.

A normal profile update may look like:

PATCH /api/v1/profile
Content-Type: application/json

{
  "name": "John",
  "phone": "+91XXXXXXXXXX"
}

The intended fields are harmless. But suppose the backend internally maintains:

json
{
  "name": "John",
  "phone": "+91XXXXXXXXXX",
  "role": "customer",
  "isVerified": false,
  "creditLimit": 50000
}

If the backend blindly maps JSON properties to the underlying object, a tester may discover that additional fields are accepted:

json
{
  "name": "John",
  "phone": "+91XXXXXXXXXX",
  "isVerified": true,
  "creditLimit": 500000
}

The impact depends entirely on which backend properties are exposed through the binding mechanism.

Fintech Example

Consider a merchant onboarding API:

PATCH /api/v1/merchant/profile

The frontend exposes three fields - business name, contact number, and address. But the underlying object also carries riskLevel, kycStatus, settlementLimit, and isApproved. If the backend accepts any of these through the same endpoint, a merchant can modify properties that are supposed to be controlled exclusively by the platform's compliance workflow.

In documented cases, merchants have been able to advance their own KYC status through mass assignment, bypassing manual review workflows and gaining access to higher settlement limits before compliance approval. The vulnerability is not in the field existing - it is in the server accepting a client-controlled value for a property that should only be modified internally.


Rate-Limit Bypass: When "Rate Limited" Does Not Mean Protected

Rate limiting is often implemented at the API gateway, WAF, application server, or authentication layer, but inconsistent enforcement can create bypass opportunities.

Consider:

POST /api/v1/otp/send

The application claims to allow five OTP requests per minute. The first thing to determine is what the limit is actually tied to. Rate limiters are commonly keyed to IP address, session token, account, device fingerprint, API key, or some combination - and the enforcement logic is often inconsistent across these dimensions. A limit keyed purely to IP address, for example, can be affected by rotating the source address through accepted infrastructure.

Common bypass vectors include header manipulation - gateways that accept X-Forwarded-For, X-Real-IP, or CF-Connecting-IP allow the apparent source IP to be rotated per request. Adding junk query parameters such as ?_=1 or ?v=2 can break cache-key-based enforcement. Trailing slash variants or case differences in endpoint paths, such as /api/v1/login versus /api/v1/login/, sometimes route around gateway rules entirely. In OTP and payment flows specifically, concurrent requests submitted within the same rate-limit window before the counter commits can bypass enforcement entirely - a race condition that is easy to miss when testing sequentially.

Banking Example

Consider a payment verification workflow:

POST /api/v1/transaction/verify-otp

If the application enforces a limit on the web endpoint but not an older mobile endpoint:

POST /api/mobile/transaction/verify

the security control becomes inconsistent. Rate-limit enforcement must therefore be evaluated across the entire attack surface, not just the primary documented endpoint.


GraphQL Abuse: One Endpoint, an Entire Application Behind It

Traditional REST applications expose many endpoints. GraphQL can consolidate large portions of an application's functionality behind a single endpoint:

POST /graphql

This changes the penetration-testing methodology. Testing a GraphQL implementation means examining more than whether the endpoint requires authentication. The schema itself is an attack surface - if introspection is enabled, a tester can map every type, field, and relationship the API exposes, including internal fields the frontend never surfaces. Beyond that, excessive query depth, recursive relationships, batch operations, and alias-based requests all warrant investigation, both for data exposure and for denial-of-service potential.

When introspection is enabled, a tester can map the entire schema - including internal types and sensitive field names the frontend never exposes - with a single query:

graphql
{
  __schema {
    types {
      name
      fields {
        name
        type { name }
      }
    }
  }
}

A subtler variant is field-level authorization bypass through aliases. Some resolvers check authorization at the query level but not per alias call:

graphql
query {
  myAccount: account(id: "A") { balance }
  otherAccount: account(id: "B") { balance }
}

This can expose data belonging to another object while appearing to the application as a single authorized request.

Consider:

graphql
query {
  customer {
    name
    email
    accounts {
      transactions {
        amount
        beneficiary
      }
    }
  }
}

The application may correctly protect individual REST endpoints but expose excessive data through GraphQL relationships.

SaaS Example

A SaaS platform might expose:

graphql
query {
  organization {
    users {
      email
      roles
      projects {
        documents {
          downloadUrl
        }
      }
    }
  }
}

A tester should ask whether the authorization model remains intact when objects are accessed through nested GraphQL relationships. A system that protects GET /users/123 may still accidentally expose the same user's information through organization → users → projects → documents.

GraphQL therefore requires testing authorization at every resolver and object relationship, rather than assuming that protecting the GraphQL endpoint itself is sufficient.


Shadow APIs: The Endpoints Nobody Remembers

Shadow APIs are endpoints that were once part of the documented API but were retired from documentation without being decommissioned from the server. This is distinct from undocumented endpoints, which were never intended to be public but remain reachable through the same infrastructure.

Shadow APIs typically originate from versioning decisions that were never fully enforced - old mobile app backends, previous API versions, forgotten microservices, development or testing environments, or interfaces brought in through acquisitions. The organization may believe the functionality was retired. The server may disagree.

Consider a company that publicly documents:

/api/v3/

During testing, the tester discovers:

/api/v1/
/api/v2/
/api/internal/
/api/mobile/
/api/legacy/

The older API may have weaker security controls. For example:

POST /api/v1/users/update

may accept fields or authorization patterns that are no longer permitted by:

PATCH /api/v3/profile

Shadow APIs are best discovered through version enumeration, archived mobile APK decompilation, Wayback Machine snapshots, and API changelog analysis. The goal is not simply to find old routes, but to determine whether they retain access to functionality that the current API has restricted or removed.

Markdown image

Undocumented Endpoints: The Attack Surface Behind the Frontend

An API penetration test should not be limited to Swagger or OpenAPI documentation. The frontend itself can reveal additional endpoints. JavaScript bundles, mobile applications, browser traffic, API calls, error messages, and third-party integrations may reveal routes that are absent from official documentation.

For example, while reviewing a SaaS web application, a tester may discover:

/api/users
/api/projects
/api/billing
/api/reports
/api/export
/api/debug
/api/internal/metrics

The documented API may contain only the first three. The concern is not that these routes exist without documentation - it's what they expose. Debug endpoints, admin operations, bulk data exports, internal identifiers, feature flags, and background job controls are all commonly found in JavaScript bundles or mobile traffic that never made it into the official API spec. An undocumented endpoint is not automatically a vulnerability, but one that exposes sensitive functionality without authentication, authorization, or monitoring is exactly that.

Undocumented endpoints surface through JavaScript bundle analysis, mobile traffic capture, DNS and subdomain enumeration, and error message inspection. Comparing these sources against the documented API helps identify functionality that exists in production but is absent from the organization's declared attack-surface inventory.

Once the actual endpoint surface is mapped, the next stage is to test how those interfaces behave when object, function, field, tenant, and rate-limit boundaries are deliberately crossed. A realistic fintech workflow demonstrates how these weaknesses can compound rather than appearing as isolated findings.


Use Case: Fintech Payment API

Consider a fictional fintech application that provides digital wallets and merchant payments. The documented payment endpoint is:

POST /api/v2/payments
Authorization: Bearer {token}

A normal customer can initiate payments from their own wallet. During testing, the tester identifies the surrounding API sequence:

GET /api/v2/wallets/{walletId}
GET /api/v2/beneficiaries/{beneficiaryId}
POST /api/v2/payments
POST /api/v2/payments/{paymentId}/cancel
POST /api/v1/payments/export

The tester creates two standard customer accounts, Account A and Account B, and uses them to establish the application's expected authorization boundaries before manipulating individual requests.

Markdown image

Object-Level Authorization

The first test focuses on whether object access is bound to the authenticated customer rather than simply to the identifier supplied in the request. The tester changes the wallet identifier from Account A's object to Account B's object:

walletId=A

and then:

walletId=B

If Account A receives Account B's wallet information, the application has a BOLA condition. The same methodology can then be applied to transaction IDs, beneficiary records, statements, documents, and other customer-owned objects to determine whether the authorization model is consistently enforced.

Function-Level Authorization

The tester then examines whether authenticated users can invoke functions reserved for higher-privileged roles. The payment cancellation endpoint is used as an example:

POST /api/v2/payments/{paymentId}/cancel

The tester submits a cancellation request against a payment that should only be cancellable by an administrative or otherwise authorized role. If the server accepts the request solely because the user is authenticated, the application is relying on authentication where function-level authorization is required.

Mass Assignment

Next, the tester examines whether payment-related requests accept properties that should be controlled exclusively by backend logic. A request such as the following may reveal whether server-controlled fields are being bound directly from client input:

json
{
  "amount": 1000,
  "currency": "INR",
  "status": "approved"
}

If a customer can manipulate a field such as status, the issue is no longer a simple input-validation weakness; it can affect transaction integrity and the application's business workflow.

Rate-Limit Testing

Rate-limit enforcement is tested independently of the web login flow. The OTP verification endpoint is checked across all three API versions - /api/v2/, /api/mobile/, and /api/v1/ - because a control enforced on one route is frequently absent on the others. The tester also evaluates whether concurrent requests, alternate path representations, or inconsistently trusted client-IP headers change the enforcement behavior.

Shadow API Discovery

Finally, the tester investigates the older payment export endpoint:

POST /api/v1/payments/export

Although absent from the current API documentation, it remains accessible. The tester compares its authentication, authorization, tenant isolation, and data-export controls with the current API implementation to determine whether the legacy route has become a weaker path to the same underlying functionality.

This illustrates why modern API testing should examine the entire ecosystem around the API rather than treating each documented endpoint as an isolated asset. In a real engagement, the findings from object-level, function-level, field-level, rate-limit, and legacy-interface testing can reveal a broader pattern of inconsistent trust boundaries.


Additional Techniques

JWT Claim Manipulation

Weakly verified tokens in banking and SaaS APIs sometimes accept modified sub, role, tenant_id, or scope claims. A tester should verify that the server validates the full token signature and rejects claims that have been altered client-side, even when the token remains structurally valid.

HTTP Method Override

Legacy banking APIs occasionally honour X-HTTP-Method-Override: DELETE sent as a POST request. WAF rules that inspect only the HTTP verb may not catch this, making it a useful technique for probing endpoints that appear protected by method restrictions.

Webhook and Callback Abuse

SaaS and fintech APIs frequently send data outbound to merchant or partner endpoints. SSRF through attacker-controlled webhook URL fields, and event injection into callback payloads, are commonly missed during API testing because testers focus on inbound requests rather than the API's outbound behavior.


Connect with QuassrCyberTech Experts

Ready to strengthen your organization's security posture?

At QuassrCyberTech, our specialized cybersecurity solutions help organizations stay ahead of evolving risks. From Vulnerability Assessment and Penetration Testing (VAPT) to Security Operations Center (SOC) implementation, Red Team exercises, and Governance, Risk, and Compliance (GRC) frameworks, we provide the expertise and tools needed to secure your digital assets and infrastructure.

Contact us today to develop a customized security strategy for your organization.


References

- OWASP Foundation - API Security Top 10

- OWASP Foundation - Web Security Testing Guide

- OWASP Foundation - GraphQL Cheat Sheet

- OWASP Foundation - Authorization Cheat Sheet

- OWASP Foundation - Mass Assignment Cheat Sheet

- OWASP Foundation - REST Security Cheat Sheet

Back to all insights
#API Security#JWT#SSRF#OWASP#Broken Function-Level Authorization#BOLA#IDOR
QuassrCyberTech | QPulse Platform
Live threat intelligence
Visit QPulse portal

Start a conversation

contactus@quasarcybertech.com+91 97306 91190

Find us

#1, State Bank Colony, Indira Nagar,
Nashik, Maharashtra 422009, India
Get in Touch

Capabilities

  • Cyber Security Advisory
  • Compliance
  • Offensive Security
  • Cloud Security
  • Managed Defense
  • Threat Intelligence

Industries

  • Banking & Financial Services
  • FinTech & Digital Payments
  • SaaS & Technology
  • E-commerce & Digital
  • Healthcare & HealthTech
  • Enterprise & Manufacturing

Platforms

  • QStellar
  • QPulse
  • QRGT
  • QLeap

Company

  • About Us
  • Case Studies
  • Blogs
  • Careers
  • Contact
  • Privacy Policy
  • Terms & Conditions
QuassrCyberTech© 2024–Present, QuasarCyberTech Private Limited. All rights reserved.