Your API Is Your Attack Surface
Ten years ago, most applications were server-rendered HTML. The attack surface was the web interface. Today, most applications are API-first. Your React or Vue frontend talks to a REST or GraphQL backend. Your mobile app uses the same API. Third-party integrations consume it. Your internal tools depend on it.
That API is your real attack surface. And in the majority of penetration tests we conduct at Sherlock Forensics, the API has more critical vulnerabilities than the web interface.
The reason is straightforward. Developers focus security efforts on what users see: the login page, the forms, the visible UI. The API layer, which handles the actual data and business logic, receives less scrutiny. Attackers know this. They skip the frontend entirely and talk directly to your API.
The OWASP API Security Top 10
The OWASP API Security Top 10 is the industry standard classification of API vulnerabilities. Here are the ones we find most frequently in real engagements, with concrete examples of how they are exploited.
1. Broken Object Level Authorization (BOLA)
OWASP API1: The single most common API vulnerability we find. Also called IDOR (Insecure Direct Object Reference).
What it looks like: Your API has an endpoint like GET /api/v1/users/123/orders. User 123 is authenticated and authorized to see their own orders. But what happens when they change the URL to GET /api/v1/users/124/orders? If the API returns user 124's orders, that is BOLA.
Why it happens: Developers build authentication (verifying who you are) but forget authorization (verifying what you can access). The API confirms you are logged in but does not check whether the resource you are requesting belongs to you.
Real impact: In one engagement, a BOLA vulnerability in a SaaS application allowed any authenticated user to download every other customer's invoices, contracts and uploaded documents by incrementing a numeric ID in the API call. Over 50,000 sensitive documents were accessible.
How to fix it: Implement server-side authorization checks on every request. Verify that the authenticated user owns or is authorized to access the specific resource. Use UUIDs instead of sequential integers to make enumeration harder (but do not rely on obscurity as your only control).
2. Broken Authentication
OWASP API2: Flaws in authentication mechanisms that allow attackers to assume other users' identities.
What it looks like: Weak JWT implementations where tokens are not validated properly, API keys transmitted in URLs and logged in server access logs, password reset tokens that are predictable or never expire, sessions that remain valid after logout and missing multi-factor authentication on sensitive operations.
Why it happens: Authentication is complex. JWT libraries have configuration pitfalls. Developers implement "happy path" authentication but do not test edge cases: What happens when a token is expired? Malformed? Signed with a different algorithm? What happens when you change your password but your old sessions stay active?
Real impact: We found an API that accepted JWTs signed with the "none" algorithm, meaning any user could forge a token for any other user (including administrators) without knowing the signing key. This gave complete access to every account in the system.
How to fix it: Use established authentication libraries (do not build your own). Validate JWTs rigorously including algorithm, expiration, issuer and signature. Invalidate all sessions on password change. Implement rate limiting on authentication endpoints. Require MFA for administrative operations.
3. Excessive Data Exposure
OWASP API3: APIs that return more data than the client application needs.
What it looks like: A user profile API returns the full user object including hashed password, internal role flags, email verification tokens and Stripe customer IDs. The frontend only displays the name and avatar. But the full response is visible to anyone who opens browser developer tools or intercepts the API call.
Why it happens: Developers query the database and return the full object, relying on the frontend to display only the relevant fields. This "filter on the client" approach treats the frontend as a security boundary, which it is not. Any data in the API response is accessible to anyone who can make the request.
Real impact: In a recent pentest, a user listing endpoint returned internal user IDs, email addresses, account creation dates, subscription tiers and hashed passwords for every user. The frontend only showed names. An attacker could harvest the entire user database by paginating through the API response.
How to fix it: Explicitly define response schemas for every endpoint. Only return the fields the client needs. Never rely on client-side filtering. Use DTOs (Data Transfer Objects) or serializers to control exactly what data leaves your API.
4. Missing Rate Limiting
OWASP API4: APIs that accept unlimited requests, enabling brute-force, credential stuffing and denial-of-service attacks.
What it looks like: Your login endpoint accepts 10,000 password attempts per second with no throttling. Your password reset endpoint lets an attacker request reset emails for every email address in existence. Your search API can be scraped at full speed to harvest your entire dataset.
Why it happens: Rate limiting is often considered an infrastructure concern rather than an application concern. Developers assume it will be handled by the API gateway, load balancer or WAF. But those layers are frequently misconfigured or bypassed entirely for internal API calls.
Real impact: We exploit missing rate limiting in almost every engagement. Without it, we can brute-force login credentials, enumerate valid usernames through registration and password reset endpoints and extract data at scale. In one case, we downloaded the entire product catalog (including wholesale pricing intended only for authorized retailers) through an unprotected API endpoint.
How to fix it: Implement rate limiting at the application level, not just the infrastructure level. Use different limits for different endpoints: authentication endpoints should be strict (5-10 attempts per minute), search endpoints moderate (100-500 requests per minute) and general API calls reasonable for legitimate usage patterns. Return HTTP 429 with a Retry-After header.
5. Mass Assignment
OWASP API6: APIs that accept and process fields the client should not be able to modify.
What it looks like: A user profile update endpoint accepts a JSON body with name, email and avatar. But the underlying data model also has fields for role, is_admin, subscription_tier and account_balance. If the API blindly maps the request body to the database model, an attacker can add "is_admin": true to their update request and escalate privileges.
Why it happens: Frameworks like Rails, Django and Laravel offer convenient model binding that automatically maps request parameters to database fields. Without explicit allowlists, every field in the model becomes writable through the API.
Real impact: In a SaaS application pentest, we upgraded a free-tier account to an enterprise subscription by adding "plan": "enterprise" to a profile update request. The API accepted it without validation. We also escalated to administrator by adding "role": "admin" to the same request.
How to fix it: Use explicit allowlists for every endpoint. Only accept the specific fields that the client is authorized to modify. Never bind request data directly to your database model without filtering. In Rails, use strong parameters. In Django, use serializer fields. In Express, validate against a schema.
6. Server-Side Request Forgery (SSRF)
OWASP API7 (related): APIs that make server-side requests based on user-supplied URLs.
What it looks like: Your API has a feature that fetches a URL: a webhook delivery endpoint, a URL preview generator, a PDF export that renders HTML from a URL, or an image proxy that resizes remote images. If the URL is user-controlled and not validated, an attacker can make your server request internal resources.
Why it happens: Developers validate that a URL looks like a URL but do not check where it points. An attacker supplies http://169.254.169.254/latest/meta-data/ (the AWS metadata endpoint) or http://localhost:6379/ (a local Redis instance) and your server obediently makes the request, returning internal data to the attacker.
Real impact: In a cloud-hosted application, we used an SSRF vulnerability in a webhook preview feature to access the AWS Instance Metadata Service. This returned temporary IAM credentials that gave us access to S3 buckets, RDS databases and other AWS resources. A single SSRF turned into a full cloud account compromise.
How to fix it: Validate and sanitize all user-supplied URLs. Block requests to private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, 127.0.0.0/8). Use allowlists of permitted domains where possible. If you are on AWS, use IMDSv2 which requires a token for metadata access. Run URL-fetching operations in a sandboxed network segment.
Why Automated Scanners Miss These
Automated API security scanners catch some of these vulnerabilities, particularly missing rate limiting and basic authentication issues. But they consistently miss BOLA, mass assignment and business logic flaws because these require understanding the application's authorization model and data relationships.
A scanner does not know that user 123 should not see user 124's data. It does not know that the role field should not be writable through the profile endpoint. It does not understand your application's business rules. A human penetration tester does.
Testing Your API
If your application has an API (and in 2026, it almost certainly does), it needs dedicated security testing. Not just a vulnerability scan. Not just a WAF in front of it. A thorough, manual assessment by someone who understands API-specific attack patterns.
Sherlock Forensics includes API security testing in every web application penetration test. Quick audits start at $1,500 CAD. Standard external assessments start at $5,000 CAD. Every engagement covers the OWASP API Security Top 10 and delivers a detailed report with severity ratings, evidence and step-by-step remediation. Learn what to expect or order online.
Frequently Asked Questions
What is API security testing?
API security testing is a specialized form of penetration testing focused on the interfaces your application uses to communicate between systems. It covers authentication, authorization, injection, data exposure, rate limiting and business logic flaws in your API endpoints. At Sherlock Forensics, API testing is included in standard pentests starting at $5,000 CAD.
What are the most common API vulnerabilities?
Based on our penetration test data, the most common API vulnerabilities are Broken Object Level Authorization (BOLA), broken authentication, excessive data exposure, missing rate limiting and mass assignment. These align with the OWASP API Security Top 10 and appear across industries and technology stacks.
How do you test API security?
We map all endpoints (including undocumented ones), test authentication mechanisms, check authorization on every endpoint with different user roles, test all input parameters for injection, verify rate limiting, check for excessive data exposure and test business logic flows. We use Burp Suite Professional, custom scripts and manual techniques tailored to your specific API architecture.