Can a stranger read another customer’s invoice just by changing a number in a URL?
That question sits at the heart of API security testing. Most modern apps are really just thin screens wrapped around APIs, and those APIs often trust whatever the client sends. Attackers know it. So do testers who write good security tests. (Best internet security australia)
This article walks through concrete API security testing examples: what the attack looks like, what the test looks like, and how to verify a fix. It leans on the OWASP API Security Top 10 as a shared vocabulary, since that list has become the de facto reference for API risk categories. The examples below are practical enough to drop into a test plan this week.
Why API Testing Breaks Traditional Security Habits
A web scanner looks at HTML forms and links. An API has neither. It has endpoints, JSON bodies, tokens, and HTTP verbs, and most of the interesting logic lives behind authentication.
That mismatch is why teams with mature web security programs still ship broken APIs. The tooling was built for pages, not for object references and mass assignment. Testers have to think in terms of who is allowed to do what to which object, then prove it with a request.
A useful mental model: every API call has three parts worth attacking — the identity (token), the target (object ID or path), and the payload (fields and values). Most real-world findings come from mismatches between those three.
Example 1: Broken Object Level Authorization (BOLA)

The attack: A user logs in, views invoice 1042, and notices the URL pattern `/api/invoices/1042`. They change it to `1043` and receive someone else’s invoice.
The test: Create two accounts, user A and user B. As A, create an object and record its ID. As B, request that same ID with B’s token. A secure API returns `403` or `404`. A vulnerable one returns `200` with A’s data.
What actually works in practice: Run this test for every endpoint that accepts an ID, including nested paths like `/users/7/orders/19`. Teams routinely lock down the top-level endpoint and forget the child resource. Also test IDs that are UUIDs — unguessable IDs are not authorization, they are just obscurity, and leaked UUIDs show up in logs, emails, and shared links all the time.
Common mistake: Testing only with an admin token. Admins can usually see everything, so the test passes and the bug ships.
Example 2: Broken Authentication and Token Handling
The attack: The API accepts an expired JWT, or a token signed with `alg: none`, or a token whose `sub` claim was edited by hand.
The test: Capture a valid token and then mutate it:
- Change one character in the signature and replay the request.
- Set the expiry claim to a past timestamp and replay.
- Swap the `alg` header to `none` and strip the signature.
- Change the user identifier claim to another user’s ID.
- Replay a token after logout to confirm server-side revocation works.
Each mutation should produce `401`. Any `200` is a finding.
Practical tip: Many testers stop at the first rejection and assume the auth layer is solid. Test the whole surface, because a single legacy endpoint, a health check, or a debug route often skips the middleware entirely. The MITRE CWE catalog classifies this family of weakness as improper authentication (CWE-287), which is a useful label for ticket titles and risk registers.
Example 3: Mass Assignment and Excessive Data Exposure
The attack: A registration endpoint accepts `{“name”:”Sam”,”email”:”sam@example.com”}`. The attacker adds `”role”:”admin”` and the server happily binds it to the user record.
The test: Take a normal request body and add every field you can guess: `role`, `isAdmin`, `verified`, `balance`, `ownerId`, `createdAt`. Send it and then fetch the object to see which fields changed. Repeat with fields the API returns but does not document — response bodies are a goldmine for field names to try.
The mirror image is excessive data exposure: the API returns a full user object including password hashes, internal flags, and other people’s emails. Test by comparing what the UI displays against what the raw JSON contains. If the response has fields the screen never uses, ask why they are there.
What works: Schema-driven testing. If the team maintains an OpenAPI spec, diff the spec against actual responses. Undocumented fields in a response are either dead weight or a leak.
Example 4: Rate Limiting and Resource Consumption
The attack: An attacker hammers `/api/login` with credential guesses, or calls an expensive search endpoint in a loop until the database buckles.
The test: Send 100 requests in quick succession to a sensitive endpoint and watch the status codes. A well-defended API returns `429` with a `Retry-After` header after a threshold. Then test the bypasses: rotate an API key, change the `X-Forwarded-For` header, or spread requests across endpoints that share the same backend cost.
Common mistake: Assuming a WAF rate limit equals application rate limiting. WAFs count requests per IP; attackers use proxies. Real protection is per-account and per-token, and it is worth verifying that the limit applies to the identity, not just the network address.
Example 5: Injection Through API Parameters
The attack: A search endpoint passes a query string straight into a database call or a shell command.
The test: Send payloads that are harmless but revealing. A single quote, a boolean pair (`’ AND ‘1’=’1` versus `’ AND ‘1’=’2`), a time delay, and a template expression like `${7*7}`. Compare responses and timing. For NoSQL backends, try operator objects such as `{“$ne”: null}` in a login field.
The OWASP Web Security Testing Guide documents structured test cases for injection across protocols, and it is worth reading the API-specific sections before writing your own. Injection in APIs is less about forms and more about JSON values, headers, and path segments, so test all three.
Example 6: Misconfigured CORS and Verb Tampering
The attack: The API reflects any `Origin` header and allows credentials. A malicious site then reads authenticated responses from a victim’s browser.
The test: Send a request with `Origin: and inspect `Access-Control-Allow-Origin` and `Access-Control-Allow-Credentials`. A reflected origin plus credentials is a finding. Wildcard origins without credentials are usually fine.
Then try verb tampering: if `GET /api/admin/users` returns `403`, try `POST`, `PUT`, `PATCH`, `DELETE`, and `HEAD`. Authorization checks are sometimes attached to specific methods only. This is a five-minute test that finds real bugs surprisingly often.
Example 7: Server-Side Request Forgery via URL Parameters
The attack: An endpoint accepts a URL — an image import, a webhook test, a PDF generator — and fetches it server-side. Point it at internal metadata services and the server hands back cloud credentials.
The test: Supply a URL you control and confirm the server calls out. Then try internal addresses and redirect chains. Blocking `127.0.0.1` as a string is not enough; test decimal and IPv6 encodings of the same address.
Practical tip: This is one of the few tests where a collaborator or request-bin style listener genuinely helps, because you need proof the server made the call.
A Workable Test Checklist
| Risk area | Quick test | Pass condition |
|---|---|---|
| BOLA | Swap object IDs between two users | 403 or 404 |
| Auth tokens | Mutate signature, expiry, claims | 401 on every mutation |
| Mass assignment | Add privileged fields to body | Fields ignored or rejected |
| Data exposure | Compare JSON to UI | No extra sensitive fields |
| Rate limits | 100 rapid requests per identity | 429 after threshold |
| Injection | Quote, boolean, timing payloads | No error or timing shift |
| CORS | Foreign Origin with credentials | Origin not reflected |
| SSRF | Internal URL in URL parameter | Request blocked |
Keep this table as a living document. Every new endpoint type gets a row, and every regression test gets a home.
Tooling That Earns Its Place
Three categories cover most needs. Interceptors like Burp Suite or OWASP ZAP let you replay and mutate requests by hand, which is where most findings are born. Scripted collections in Postman or a code-based runner like pytest with `requests` turn manual tests into repeatable suites you can run in CI. Spec linters catch missing auth declarations and undocumented fields before anyone sends a packet.
For teams also securing the infrastructure around the API, gateway choice matters as much as the tests. A comparison of Kong vs AWS API Gateway vs Apigee in 2026 is a reasonable starting point, and non-human identity is the next frontier — see this breakdown of Astrix vs Oasis vs Entro for non-human identity security for how machine credentials get governed.
None of that replaces testing. A gateway enforces policy; a test proves the policy holds on the endpoints you actually shipped.
How to Prioritize When Everything Looks Broken
Start with anything that touches money, identity, or other people’s data. BOLA and broken authentication top the list because they are the most exploited and the most damaging. Injection and SSRF come next because impact is high even if frequency is lower. Configuration issues like CORS and verb tampering are cheap to test and cheap to fix.
Then, and this matters, write the regression test at the same time you write the fix. A finding without a test is a finding you will rediscover in eighteen months. (Application programming interface)
Conclusion
Good API security testing is not exotic. It is a disciplined habit of asking three questions for every endpoint: who is calling, what are they allowed to touch, and what happens if they lie about both. The examples above — BOLA, token mutation, mass assignment, rate limits, injection, CORS, SSRF — cover the failures that show up again and again in real assessments.
Pick two from the checklist, run them against your own API today, and write down what you find. That single afternoon teaches more than any framework summary, and it gives the next test a place to start.
Frequently Asked Questions
What is the most common API security flaw found in testing?
Broken object level authorization, often called BOLA or IDOR, is consistently the top finding. It happens when an endpoint accepts an object ID and returns the record without checking that the caller owns it. The test is simple: request another user’s object with your own token and see whether the server refuses.
Do I need special tools to test API security?
No. A proxy that can intercept and replay requests covers most manual testing, and a scripted HTTP client covers regression. Specialized scanners help with breadth, but the highest-value findings usually come from a tester reasoning about authorization and then confirming it with a single crafted request.
How is API testing different from web application testing?
Web testing focuses on pages, forms, and browser behavior. API testing focuses on endpoints, tokens, object references, and payloads, with no rendered UI to inspect. Many vulnerabilities live in logic that a browser never exposes, so scanners built for HTML find little. Testers need to work at the request level.
How often should API security tests run?
Authorization and authentication tests should run on every build that touches an endpoint, ideally as automated checks in the pipeline. Deeper manual testing makes sense before major releases and whenever a new endpoint type or auth flow ships. A quarterly full pass catches drift.
Can rate limiting alone stop credential stuffing?
No. Rate limiting raises the cost but does not stop distributed attempts from many addresses. Layer it with breached-password checks, multi-factor authentication, and anomaly detection on login patterns. Test that limits apply per account and per token, not just per IP address.
What should a security test report include?
Each finding needs the request that triggers it, the response that proves it, the affected endpoint, the impacted data, and a suggested fix. Include a reproduction script so a developer can confirm the fix themselves. Reports without a reproducible request tend to get argued with rather than fixed.


