The OWASP API Security Top 10 exists as a separate list from the main OWASP Top 10 because APIs have a distinct attack surface. There's no UI to guide exploration — everything is exposed programmatically, authenticated state is complex, and the data exchanged is often more sensitive than what a browser receives.
The sections below cover the five most commonly exploited items from that list. Here's how to approach each one systematically.
API1: Broken Object Level Authorization (BOLA)
The most common API vulnerability. An endpoint accepts an object ID and returns the object without checking whether the requesting user owns it.
GET /api/v1/orders/8472
Authorization: Bearer user_a_token
# Returns user_b's order if the API doesn't check ownership
How to test: Authenticate as User A. Collect IDs from normal API use. Authenticate as User B. Attempt to access User A's IDs. A 200 response is a confirmed BOLA vulnerability.
How to fix: Every query that retrieves a resource by ID must filter by the authenticated user: WHERE id = $1 AND user_id = $2.
API2: Broken Authentication
Authentication flaws specific to APIs: tokens that don't expire, JWTs that aren't validated, authentication endpoints with no rate limiting, or API keys in URLs (logged by proxies and servers).
# JWT with algorithm:none accepted — attacker removes signature and sets alg:none
# Test: decode your JWT, modify the payload, use alg:none, send it
eyJhbGciOiJub25lIn0.eyJ1c2VySWQiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ.
How to test: Check if expired tokens are accepted. Try alg:none JWT bypass. Test login endpoint rate limiting (automate 100 attempts). Look for API keys in query params in your logs.
API3: Broken Object Property Level Authorization
The API returns more fields than the user should see, or accepts more fields in writes than intended (mass assignment).
# Excessive data exposure: returns password hash and internal IDs
GET /api/v1/users/me
{
"id": 123,
"email": "[email protected]",
"passwordHash": "$2b$10$...",
"stripeCustomerId": "cus_abc"
}
# Mass assignment: API accepts fields it shouldn't
PATCH /api/v1/users/me
{"email": "[email protected]", "role": "admin"} # role accepted?
How to test: Inspect all API responses for fields that shouldn't be client-visible. Try adding unexpected fields in write requests (role, isAdmin, subscription). Use a field enumeration tool to discover undocumented properties.
API4: Unrestricted Resource Consumption
Missing rate limits on expensive endpoints. No pagination limits. Endpoints that allow arbitrary-size array inputs. Webhooks that can be triggered at unlimited frequency.
# Test: send a large batch request
POST /api/v1/users/bulk-lookup
{"ids": [1,2,3,...,10000]} # does the server process all 10,000?
# Test: rapid-fire the search endpoint
for i in {1..1000}; do curl /api/search?q=test; done
How to fix: Rate limiting at the reverse proxy or API gateway layer. Explicit max page sizes and max batch sizes. Request size limits.
API5: Server-Side Request Forgery (SSRF)
An API endpoint that fetches a user-supplied URL. In cloud environments, this is critical — an attacker provides the AWS metadata endpoint URL and gets temporary credentials.
# Test: provide cloud metadata URLs as inputs to any URL-accepting parameter
POST /api/v1/webhooks
{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}
POST /api/v1/import
{"imageUrl": "http://[::ffff:169.254.169.254]/latest/meta-data/"} # IPv6 bypass
How to fix: Allowlist valid URL schemes and domains for any endpoint that fetches external URLs. Block private IP ranges and cloud metadata endpoints in egress filtering.
Systematic API testing approach
Step 1: API discovery
You can't test what you don't know about. Map all endpoints by examining:
- OpenAPI/Swagger specs (if available)
- Network traffic from the frontend (browser DevTools Network tab)
- JavaScript source for fetch calls and API client constructors
- Crawler discovery against running endpoints
Step 2: Authentication coverage
For every endpoint, test it with: no auth token, an expired token, a valid token for a different user, a valid token for a lower-privilege role. Any unexpected 200 response is a finding.
Step 3: Input fuzzing
Send unexpected values to every input field: SQL payloads, XSS payloads, path traversal sequences, very large values, negative numbers, null, arrays where scalars are expected. Look for error messages that reveal stack traces or database structure.
Step 4: Business logic testing
This requires understanding your application. Can you apply a coupon twice? Order negative quantities? Access a resource in a state where it shouldn't be accessible (e.g., a soft-deleted item)? This is the manual pentester's territory.
How BattleTest tests APIs
BattleTest's live battletest crawler identifies API endpoints and their parameter shapes, then runs targeted security tests: BOLA testing with two-session cross-access, injection payload fuzzing against JSON body fields, header analysis for auth weaknesses, and SSRF payload injection into URL-type parameters. Findings include confirmed reproduction steps — not just "potential vulnerability."