REST APIs are the backbone of modern applications. Every mobile app, single-page application, microservice, partner integration, and internal tool talks to one. They handle authentication, process transactions, move sensitive data between systems, and enforce the business rules your application depends on. They are also, consistently, the most attacked surface we encounter in penetration testing engagements.
The challenge with API security is visibility. When you test a web application, you can see the forms, the buttons, the navigation. The UI tells you what the application does. APIs have no UI. Their attack surface is hidden behind endpoints that most security teams never fully enumerate, protected by authorization logic that nobody has comprehensively tested, and documented in specs that are months or years out of date.
Our REST API penetration testing methodology is structured in five phases, each building on the one before it. It goes well beyond the OWASP API Security Top 10 to cover the real-world attack chains we see threat actors exploiting in production. This article walks through each phase in detail: what we test, how we test it, and why it matters.
Phase 1: API Discovery and Reconnaissance
You cannot secure what you do not know exists. The first phase of every API penetration test is building a complete map of the API's attack surface. In our experience, the documented API surface typically represents 60 to 70 percent of the actual endpoints in production. The rest are undocumented, deprecated, internal, or accidentally exposed. Those are usually the ones with the most critical vulnerabilities.
Finding undocumented endpoints
We start by collecting every endpoint we can find through documentation: OpenAPI/Swagger specs, Postman collections, API reference pages, developer portals. But we never stop there. Undocumented endpoints are found through several techniques that we run in parallel.
JavaScript file analysis is one of the highest-yield techniques. Single-page applications contain API endpoint URLs in their bundled JavaScript. We download every JS file the application serves, then extract URL patterns, path segments, and API base URLs. Tools like LinkFinder and custom regex extraction routinely reveal admin endpoints, internal API routes, and deprecated paths that the public documentation never mentions.
API endpoint fuzzing uses curated wordlists against the API's base URL to discover paths that respond with anything other than a 404. We use wordlists specific to the technology stack, common REST conventions (/api/v1/users, /api/v2/admin, /api/internal/), and patterns observed elsewhere in the API. A well-crafted wordlist against a real API consistently uncovers endpoints that were not in any documentation.
Mobile application decompilation is essential when the API serves a mobile client. Android APKs decompiled with jadx or apktool expose hardcoded API endpoints, authentication flows, and sometimes API keys or tokens embedded in the binary. iOS applications require slightly different tooling but yield the same results. Mobile clients frequently call endpoints that the web frontend does not, revealing additional attack surface.
Swagger and OpenAPI spec hunting involves checking common paths where specs are inadvertently left accessible in production: /swagger.json, /openapi.json, /api-docs, /v1/api-docs, /swagger-ui.html, /swagger/v1/swagger.json. These files, when found, provide a complete schema including endpoint paths, parameter types, request bodies, and authentication requirements. We find exposed Swagger specs in roughly one out of every four API pentests.
Understanding the authentication model
Before testing any endpoint, we map exactly how the API authenticates requests. Is it JWT bearer tokens? OAuth2 with authorization code flow? API keys in headers? Session cookies? A combination? We identify where tokens are issued, how they are validated, what claims they contain, and whether different endpoints use different authentication mechanisms. This understanding is critical for every subsequent phase.
Mapping HTTP methods and API versioning
Every discovered endpoint is tested with all standard HTTP methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, and HEAD. An endpoint that returns 405 Method Not Allowed for DELETE might accept PUT with no authorization check. We also enumerate API versions. If /api/v2/users is the current version, we test /api/v1/users, /api/v3/users, and version-less paths. Deprecated API versions frequently lack the security controls added in later versions but still have full access to the same backend data.
Rate limit testing on discovery
During discovery, we assess whether the API enforces rate limits on unauthenticated requests. APIs that allow unlimited unauthenticated requests to any endpoint are vulnerable to enumeration attacks, credential stuffing, and denial-of-service. We note the rate limiting behavior early because it affects how we conduct every subsequent test.
Tooling for Phase 1
Our discovery toolkit includes Burp Suite Professional for traffic interception and analysis, Postman for organizing discovered endpoints into testable collections, custom wordlists tailored to the target's technology stack and naming conventions, ffuf and feroxbuster for directory and endpoint fuzzing, and LinkFinder for JavaScript endpoint extraction. The output of this phase is a comprehensive endpoint inventory that serves as the testing scope for everything that follows.
Phase 2: Authentication and Authorization Testing
This is the phase where we find the most critical vulnerabilities. Authentication and authorization flaws account for more high and critical severity findings in our API pentests than all other categories combined. The reason is straightforward: a single authorization bypass can expose every record in the database, while an injection vulnerability typically affects one parameter on one endpoint.
JWT vulnerabilities
JSON Web Tokens are the dominant authentication mechanism in REST APIs, and they are routinely implemented with critical flaws. We test for every known JWT attack vector.
Algorithm confusion exploits APIs that accept multiple signing algorithms. If the API uses RS256 (asymmetric), we attempt to switch the algorithm header to HS256 (symmetric) and sign the token using the server's public key as the HMAC secret. Since the public key is, by definition, public (often available at /.well-known/jwks.json), a successful attack gives us the ability to forge arbitrary tokens.
The "none" algorithm attack is simpler: we change the algorithm header to "alg": "none", modify the payload claims to escalate privileges or impersonate another user, remove the signature, and submit the token. Modern JWT libraries reject this by default, but custom implementations and older library versions still accept it. We find this in production more often than you would expect.
Weak signing keys for HS256 tokens can be cracked offline. We run every HS256 token through hashcat (mode 16500) with a curated list of common secrets. Keys like secret, password123, company names, and default framework values crack in seconds. A cracked signing key means we can forge tokens for any user, including administrators.
Expired token acceptance is tested by modifying the exp claim to a past timestamp and verifying whether the API still accepts the token. APIs that decode JWT claims for user identity but skip expiration validation effectively make every token permanent. We also test whether tokens issued before a password change or logout are properly invalidated.
OAuth2 misconfigurations
OAuth2 implementations introduce a distinct set of vulnerabilities. Authorization code injection occurs when an attacker can substitute their own authorization code into a victim's callback flow, linking the victim's account to the attacker's identity provider. PKCE bypass is tested on public clients (mobile apps, SPAs) where the code_verifier validation is missing or incorrectly implemented. Scope escalation involves requesting broader scopes than the application should allow, checking whether the authorization server enforces scope restrictions, and testing whether tokens with elevated scopes are accepted by the resource server.
API key security
We assess how API keys are transmitted, stored, and managed. Keys passed in URL query parameters are logged by proxies, CDNs, browser history, and server access logs, creating multiple exposure points. We check whether keys are present in client-side JavaScript bundles, mobile application binaries, and public code repositories. We test whether key rotation is possible and whether old keys are actually invalidated after rotation.
BOLA/IDOR testing across all endpoints
Broken Object Level Authorization is the single most common critical vulnerability in REST APIs. For every endpoint that accepts a resource identifier (user ID, document ID, order number, account reference), we substitute identifiers belonging to other users. We test with two or more authenticated sessions at the same privilege level (horizontal BOLA) and across privilege levels (vertical BOLA). We test identifiers in URL paths, query parameters, request bodies, and headers. Burp Suite's Autorize extension automates much of this by replaying every request with a different user's session token, but the critical analysis, determining whether the returned data belongs to the wrong user, requires human judgment.
Broken Function Level Authorization
We build a full authorization matrix: every API endpoint mapped against every user role. For an API with five user roles and 100 endpoints, that is 500 authorization checks. We test standard users calling admin endpoints, read-only users attempting write operations, free-tier users accessing premium features, and one tenant's users accessing another tenant's resources. Horizontal privilege escalation (User A performing actions as User B at the same privilege level) and vertical privilege escalation (a regular user performing admin actions) are both tested systematically.
Mass assignment testing
For every endpoint that accepts user input and modifies a resource, we add additional fields to the request body that the user should not control. Common targets include role, isAdmin, permissions, verified, balance, tier, and plan. We identify candidate fields by examining GET response bodies (which often return more fields than the PUT/PATCH endpoint expects), reading API documentation for the full data model, and analyzing frontend JavaScript for TypeScript interfaces or data models that reveal internal field names.
Phase 3: Input Validation and Injection Testing
Traditional injection vulnerabilities have not disappeared in REST APIs. They have migrated from HTML forms into JSON request bodies, query parameters, HTTP headers, and URL path segments. The assumption that "our API only accepts JSON, so injection is not a concern" is one of the most dangerous misconceptions we encounter.
SQL injection through API parameters
We test for SQL injection in every input vector: JSON body fields, query parameters, URL path segments, and HTTP headers (including less obvious ones like X-Forwarded-For, Referer, and custom headers). JSON string values are the most common injection point, but numeric and boolean fields are also tested because they may be interpolated directly into SQL queries without type checking. We use both manual payloads tailored to the suspected database backend and automated tools like SQLMap configured for JSON content types.
NoSQL injection
APIs backed by MongoDB or other document databases are tested for NoSQL injection using MongoDB query operators embedded in JSON request bodies. A login endpoint that accepts {"username": "admin", "password": {"$ne": ""}} authenticates as admin if the backend passes the request body directly to a MongoDB query. We test $gt, $ne, $regex, $where, and $or operators across all input fields, looking for responses that indicate query manipulation.
Command injection
API endpoints that process user-supplied input through system commands are tested for command injection. Common targets include file conversion endpoints, image processing, PDF generation, DNS lookup tools, and any endpoint that accepts hostnames, URLs, or file paths as parameters. We inject command separators (;, |, &&, backticks, $()) and observe response timing and content for evidence of execution.
Server-Side Request Forgery (SSRF)
Any API parameter that accepts a URL is a potential SSRF vector. Webhook callback URLs, image URLs for avatar uploads, import-from-URL features, and PDF generation from URLs are the most common targets. We test whether the API can be directed to make requests to internal network addresses (127.0.0.1, 169.254.169.254 for cloud metadata, internal hostnames, RFC 1918 addresses) and whether URL validation can be bypassed through DNS rebinding, URL encoding, or redirect chains.
XML External Entity (XXE) injection
Even in REST APIs that primarily use JSON, we test whether the API accepts XML by changing the Content-Type header to application/xml or text/xml and sending an equivalent XML payload. Many API frameworks process multiple content types automatically. If the API processes XML, we inject external entity declarations to read local files, make outbound network requests, or cause denial-of-service through recursive entity expansion (the "billion laughs" attack).
Server-side template injection
API endpoints that generate dynamic content, email templates, PDF reports, or personalized responses may be vulnerable to server-side template injection. We inject template syntax specific to common engines (Jinja2, Twig, Freemarker, Handlebars) into fields likely to be rendered through a template engine. Expressions like {{7*7}} returning 49 in the response confirm template injection, which can escalate to remote code execution.
Header injection
We test for injection through HTTP headers that the API processes: Host header manipulation for password reset poisoning, X-Forwarded-For injection to bypass IP-based access controls, and custom headers that may be logged, displayed, or processed without sanitization. Header injection can lead to cache poisoning, log injection, and in some cases, HTTP response splitting.
For APIs that also expose a GraphQL endpoint alongside REST, we extend injection testing to cover GraphQL-specific vectors including introspection queries, nested query depth attacks, and batching-based rate limit bypasses. Many modern applications expose both REST and GraphQL interfaces backed by the same data layer, and vulnerabilities in one surface can inform exploitation of the other.
Phase 4: Business Logic Testing
Business logic vulnerabilities are, by definition, impossible for automated scanners to detect. They require understanding what the application is supposed to do and testing what happens when those assumptions are violated. This phase is entirely manual and is where experienced penetration testers provide the most value over automated tools.
Race conditions in financial transactions
Any endpoint that modifies a balance, transfers value, or processes a payment is tested for time-of-check-to-time-of-use (TOCTOU) race conditions. We send concurrent requests to transfer the same funds, redeem the same credit, or apply the same one-time discount. The test involves firing 20 to 50 simultaneous requests using Burp Suite's Turbo Intruder or custom threading scripts, then checking whether the operation was applied multiple times. A race condition in a payment endpoint can turn a single $100 credit into $5,000.
Workflow bypass
Multi-step processes (checkout flows, KYC verification, approval chains) are tested by skipping steps, reordering steps, and replaying earlier steps after completing later ones. If a checkout flow goes from cart to address to payment to confirmation, we test whether submitting the confirmation request directly (without completing the payment step) results in a free order. We test whether verification status can be set by repeating an earlier API call after the verification was revoked.
Price and value manipulation
Every parameter that represents a monetary value, quantity, discount, or price is tested for manipulation. We modify prices in the request body, submit negative quantities, apply percentage discounts that exceed 100 percent, and chain multiple discount mechanisms. If the price is calculated client-side and submitted to the API, the API must validate it server-side. We verify that it does by changing the submitted price to $0.01, to a negative value, and to a mismatched value.
Coupon and discount abuse
Discount codes are tested for reuse (applying the same code multiple times), stacking (applying multiple codes to a single transaction), and manipulation (modifying discount values or percentage parameters). We also test whether coupon validation happens at application time or at final checkout, since validation that only happens at one step can be bypassed by modifying the request at the other step.
Pagination and filter manipulation
Pagination parameters like page, limit, offset, and per_page are tested with extreme values. Requesting ?limit=999999 can cause memory exhaustion or reveal all records at once, bypassing server-side pagination controls. Filter parameters are tested for bypass: if an API endpoint filters results by the authenticated user's ID, we test whether adding or modifying the filter parameter (?user_id=all, ?user_id=*, removing the parameter entirely) returns records belonging to other users.
Bulk operation abuse
APIs that support bulk operations (batch create, bulk delete, mass update) are tested for authorization bypass at scale. If a single-record endpoint enforces authorization correctly, the bulk equivalent may not check authorization on every individual record in the batch. We submit bulk requests containing a mix of authorized and unauthorized resource IDs to determine whether the API validates each item individually or only validates the first item and processes the rest blindly.
Phase 5: Data Exposure and Information Leakage
The final phase focuses on what the API reveals, both in normal operation and when errors occur. Data exposure vulnerabilities are often overlooked because they do not involve active exploitation, but they provide attackers with the information needed to launch more targeted attacks.
Excessive data in API responses
We examine every API response for data that should not be returned. Common findings include password hashes in user profile responses, internal database IDs that enable BOLA attacks, PII fields (SSN, date of birth, full addresses) in endpoints that only need a name and email, debug information like query execution times or internal server paths, and other users' data inadvertently included in list responses. The fix is straightforward (use response DTOs or serialization allowlists), but the finding is pervasive because developers return full database objects and rely on the frontend to display only what is needed.
Error message information disclosure
We trigger errors through malformed requests, invalid types, missing parameters, and boundary values, then analyze the error responses. Production APIs should return generic error messages. Instead, we frequently find SQL query fragments in database errors, full stack traces with file paths and line numbers, internal service names and IP addresses, framework version information, and authentication mechanism details that aid in crafting bypass attacks.
API versioning exposing deprecated endpoints
Older API versions that remain accessible often have weaker security controls. A /v1/ endpoint might lack the rate limiting, input validation, or authorization checks added in /v2/, while still having full access to the same backend data. We test every discovered API version for functionality that was removed from newer versions but remains operational in the old version.
CORS misconfiguration
Cross-Origin Resource Sharing misconfigurations can allow unauthorized websites to make authenticated API requests on behalf of a user. We test whether the API reflects arbitrary Origin headers in its Access-Control-Allow-Origin response, whether it accepts null origins, and whether the origin validation can be bypassed through subdomain matching weaknesses (e.g., attacker-lorikeetsecurity.com matching a *.lorikeetsecurity.com pattern). A misconfigured CORS policy combined with a data-returning endpoint creates a cross-origin data theft vulnerability.
Sensitive data in HTTP headers
Response headers are inspected for information leakage: Server headers revealing exact software versions, X-Powered-By headers exposing the technology stack, custom debug headers left from development, and internal routing headers that reveal infrastructure topology. While individually low-severity, these findings assist attackers in targeting version-specific exploits.
Automated API Scanning vs. Manual API Penetration Testing
We are frequently asked whether automated API scanning tools can replace manual penetration testing. The short answer is no. The longer answer is in this comparison.
| Testing Area | Automated API Scanning | Manual API Penetration Testing |
|---|---|---|
| BOLA/IDOR Detection | Almost never detected; requires understanding object ownership across user contexts | Systematically tested across every endpoint with multiple authenticated sessions |
| Business Logic Flaws | Not detected; scanners cannot understand intended application behavior | Tested through workflow bypass, race conditions, price manipulation, and abuse scenarios |
| Authentication Bypass | Partially detected; can catch missing auth but not complex JWT or OAuth2 flaws | Full JWT attack suite, OAuth2 flow analysis, token manipulation, and session testing |
| Rate Limit Bypass | Basic detection; checks if rate limiting exists but not whether it can be bypassed | Tests header spoofing, endpoint variation, account rotation, and concurrency-based bypasses |
| Data Exposure | Partially detected; can flag verbose errors but not context-specific data leakage | Analyzes every response for PII, internal IDs, debug info, and excessive data relative to endpoint purpose |
| False Positive Rate | High; typically 30-60% of findings require manual triage | Very low; every finding is validated through exploitation with proof-of-concept |
| Coverage Depth | Broad but shallow; checks known vulnerability signatures across many endpoints | Deep and contextual; tests application-specific logic and chained attack paths |
Automated scanning has its place. It catches known CVEs, missing security headers, and basic misconfigurations quickly and at scale. But the vulnerabilities that lead to data breaches in REST APIs, the BOLA flaws, the broken authorization checks, the business logic bypasses, require a human tester who understands the application.
OWASP API Security Top 10 (2023) Methodology Mapping
Every OWASP API Security Top 10 item maps directly to one or more phases in our testing methodology. Here is how our 5-phase approach provides complete coverage.
- API1:2023 - Broken Object Level Authorization (BOLA): Covered in Phase 2 through systematic BOLA/IDOR testing across every endpoint with multiple authenticated sessions and identifier substitution in paths, query parameters, and request bodies.
- API2:2023 - Broken Authentication: Covered in Phase 2 through JWT vulnerability testing (algorithm confusion, none algorithm, weak keys, expiration bypass), OAuth2 misconfiguration testing, and API key security assessment.
- API3:2023 - Broken Object Property Level Authorization: Covered in Phase 2 through mass assignment testing and in Phase 5 through excessive data exposure analysis. We test both what users can read (data exposure) and what they can write (mass assignment).
- API4:2023 - Unrestricted Resource Consumption: Covered in Phase 1 through rate limit assessment during discovery and in Phase 4 through pagination manipulation and bulk operation abuse testing.
- API5:2023 - Broken Function Level Authorization: Covered in Phase 2 through comprehensive authorization matrix testing, including horizontal and vertical privilege escalation across all user roles and all endpoints.
- API6:2023 - Unrestricted Access to Sensitive Business Flows: Covered in Phase 4 through business logic testing, including race conditions, workflow bypass, coupon abuse, and automated abuse of legitimate features.
- API7:2023 - Server Side Request Forgery (SSRF): Covered in Phase 3 through SSRF testing on every URL-accepting parameter, including internal network access, cloud metadata endpoint access, and URL validation bypass techniques.
- API8:2023 - Security Misconfiguration: Covered across all phases: verbose error messages (Phase 5), missing rate limiting (Phase 1), CORS misconfiguration (Phase 5), unnecessary HTTP methods (Phase 1), and exposed debug endpoints (Phase 1).
- API9:2023 - Improper Inventory Management: Covered in Phase 1 through comprehensive endpoint discovery, deprecated API version testing, undocumented endpoint fuzzing, and Swagger/OpenAPI spec hunting.
- API10:2023 - Unsafe Consumption of APIs: Covered in Phase 3 through testing how the API processes data from external sources, and in Phase 4 through webhook and callback manipulation testing.
Common REST API Vulnerabilities We Find
These are real vulnerabilities from recent engagements, anonymized to protect our clients. They illustrate the types of findings that automated scanners consistently miss.
BOLA on user profile endpoint
A SaaS platform's API returned complete user profiles including email, phone number, billing address, and subscription details when any authenticated user changed the user ID in the request path. The endpoint checked that the requester had a valid session token but did not verify that the token belonged to the user whose profile was being requested. A single authenticated account could enumerate every user in the system by incrementing the ID. We reported this as critical severity. The fix was a single authorization check: verify that request.user.id matches the requested profile ID, or that the requester has an admin role.
JWT with "none" algorithm accepted
A fintech application's API used JWTs for authentication but accepted tokens signed with the "none" algorithm. We decoded a valid token, changed the alg header to "none", modified the user_id and role claims to impersonate an admin, removed the signature, and the API accepted it. Full administrative access to every account, every transaction, and every configuration setting. The root cause was a custom JWT validation function that checked the signature only when an algorithm was specified, treating "none" as "no signature needed."
Mass assignment creating admin accounts
A B2B platform's user registration endpoint accepted a JSON body with name, email, and password fields. We added "role": "admin" to the registration request. The API created the account with admin privileges. The backend used an ORM that mapped all request body fields directly to the database model without a field allowlist. Any new user could self-provision an admin account. The registration endpoint had been audited for input validation (password strength, email format), but nobody had tested whether it accepted fields beyond the three shown in the UI.
SSRF through webhook URL parameter
An application allowed users to configure webhook URLs for event notifications. We set the webhook URL to http://169.254.169.254/latest/meta-data/iam/security-credentials/, the AWS instance metadata endpoint. The application's server made the request and returned the response through the webhook test feature, exposing the IAM role name. A follow-up request to the role-specific credentials endpoint returned temporary AWS access keys with broad permissions. The SSRF provided a path from the application layer to the underlying cloud infrastructure.
Rate limit bypass via header manipulation
An API enforced rate limiting on the login endpoint: 10 attempts per IP address per minute. The rate limiter used the X-Forwarded-For header to identify the client IP. The header was not validated against a trusted proxy list, so we spoofed a different IP address with each login attempt. With unlimited attempts, we brute-forced a four-digit PIN-based authentication system in under three minutes. The fix required validating X-Forwarded-For against known load balancer IPs and adding per-account rate limiting in addition to per-IP rate limiting.
In our experience, over 80% of REST APIs we test have at least one BOLA vulnerability. Most automated scanners miss these entirely because detecting them requires understanding the application's authorization model. A scanner can send requests and observe responses, but it cannot determine whether the data returned belongs to the requesting user or to someone else. That determination requires multiple authenticated contexts, knowledge of object ownership, and the judgment to recognize when a successful response is actually a security failure.
Getting Started with API Security Testing
If your organization relies on REST APIs, and in 2026, virtually every organization does, the question is not whether you have API vulnerabilities. It is how many, and how critical they are. The vulnerabilities described in this article exist in APIs of every size, from early-stage startups with a dozen endpoints to enterprise platforms with thousands.
A structured API penetration test, following a methodology like the five phases above, is the most reliable way to find what automated tools miss. The authentication bypasses, the authorization gaps, the business logic flaws, and the data exposure issues that lead to real breaches are found through manual testing by experienced testers who understand both the technical attack surface and the business context.
If you are building or maintaining APIs, start by ensuring you have a complete inventory of every endpoint, including the ones that are not in your documentation. Implement object-level authorization on every endpoint that returns or modifies data tied to a specific user or resource. Use an authorization framework rather than ad-hoc checks scattered across your codebase. And schedule regular API security assessments that go beyond automated scanning.
For organizations preparing for compliance audits, API penetration testing is increasingly a specific requirement. SOC 2 auditors, PCI-DSS assessors, and ISO 27001 certification bodies expect to see evidence of manual API testing, not just automated scan reports. If you are working toward any of these certifications, an API pentest should be part of your readiness plan. You can see the full range of our testing capabilities on our service areas page.
Need Your REST API Tested?
Our API security testing methodology covers the full OWASP API Security Top 10 and the business logic vulnerabilities that scanners miss. We deliver detailed findings with proof-of-concept exploits and prioritized remediation guidance.