API Security Testing: OWASP API Top 10 Checklist with Examples
APIs now carry most of the world’s sensitive data: payments, health records, KYC documents, location history. Attackers know it, and most large data breaches of recent years trace back to an API that trusted the wrong request. You don’t need to be a penetration tester to catch these bugs. In this lesson you’ll learn the OWASP API Security Top 10 in plain language, with a real-life example and concrete test cases for each risk that any QA engineer can run.
Why QA Engineers Must Test API Security
- Security teams run penetration tests once or twice a year; QA tests every sprint.
- The most common API vulnerabilities are logic bugs (wrong ownership checks, missing limits), not exotic exploits. Testers who know the business rules find them best.
- Fixing a security bug before release costs a fraction of a breach: fines under data protection laws like India’s DPDP Act and GDPR, incident response and lost customer trust.
OWASP API Security Top 10 at a Glance
| # | Risk | In one line | Quick tester check |
|---|---|---|---|
| API1 | Broken Object Level Authorization | Access others’ records by changing an id | User A requests user B’s order id |
| API2 | Broken Authentication | Weak login, tokens or sessions | Brute force, expired/tampered tokens |
| API3 | Broken Object Property Level Authorization | Read or write fields you shouldn’t | Send "role":"admin"; look for leaked fields |
| API4 | Unrestricted Resource Consumption | No limits on size, rate or cost | per_page=100000, 1,000 requests/min |
| API5 | Broken Function Level Authorization | Normal users call admin functions | Viewer calls DELETE or /admin endpoints |
| API6 | Unrestricted Access to Sensitive Business Flows | Automating flows that hurt the business | Bot buys all concert tickets, coupon farming |
| API7 | Server-Side Request Forgery (SSRF) | API fetches an attacker-chosen URL | Image URL = http://169.254.169.254/ |
| API8 | Security Misconfiguration | Bad defaults, verbose errors, CORS | Stack traces, open CORS, missing headers |
| API9 | Improper Inventory Management | Forgotten old/debug APIs | /v1/, /beta/, staging exposed |
| API10 | Unsafe Consumption of APIs | Trusting third-party API data blindly | Partner returns malicious data or redirects |
API1: Broken Object Level Authorization (BOLA)
/api/bills/7845123. Changing the number shows other customers’ names, addresses and call records. Data leaks of exactly this shape are among the most reported API vulnerabilities.Tests: two users of the same role; access each other’s resources via path, query and body ids; check list endpoints don’t return other users’ items; expect 403/404. Full method in Authorization Testing.
API2: Broken Authentication
Tests: no rate limit on login or OTP; tokens without expiry; tokens accepted after logout; weak password rules; different messages for wrong user vs wrong password; credentials in URLs; alg: none JWTs. The practice API rejects tampered, expired and revoked tokens, so you can see correct behaviour; the JWT lesson has all the steps.
API3: Broken Object Property Level Authorization
Two halves: excessive data exposure (the response contains fields the UI hides, like password_hash, pan_number, internal flags) and mass assignment (the client can set fields like role, price, is_verified).
Tests: inspect every response field, not just what the screen shows; validate with a JSON Schema that has additionalProperties: false; send privileged fields in POST/PUT/PATCH and confirm they’re rejected or ignored.
API4: Unrestricted Resource Consumption
Every API call costs CPU, memory, database time and sometimes money (SMS, email, AI calls). Without limits, one user can slow down everyone or run up a huge bill.
| Test | Practice API behaviour |
|---|---|
| Huge page size | per_page=51 → 400 (max 50) |
| Large body | Over 10 KB → 413 |
| Rate limit | /rate-limit: 6th call in a minute → 429 + Retry-After; whole API: 600/min per IP |
| Long-running requests | /delay/11 → 400 (max 10 s) |
| Expensive operations | Send 1,000 “forgot password” SMS requests → should be throttled |
https://sqatools.in/wp-json/sqa-api/v1/rate-limitcurl -i \
"https://sqatools.in/wp-json/sqa-api/v1/rate-limit"Press Send six times quickly. Watch X-RateLimit-Remaining count down, then the 429.
API5: Broken Function Level Authorization
Tests: call admin endpoints with a normal user token; try methods the UI never uses (DELETE, PUT); guess admin paths (/admin, /internal, /manage); check role changes take effect. On the practice API a viewer token on POST /token/objects correctly returns 403.
API6: Unrestricted Access to Sensitive Business Flows
Tests: can one account or device buy beyond the limit per user? Can the same coupon or referral be redeemed repeatedly via the API? Are there controls such as device fingerprinting, CAPTCHA at the UI, per-user quotas and anomaly detection? Discuss these flows with the business team; they know what “abuse” means for them.
API7: Server-Side Request Forgery (SSRF)
Any feature where the API fetches a URL you supply (import from URL, profile picture URL, webhook URL, PDF generation from a link) can be abused to make the server call internal systems.
Tests (in authorised test environments only): supply http://localhost/, http://127.0.0.1:8080/admin, internal IPs (10.x, 192.168.x), the cloud metadata address http://169.254.169.254/, file:///etc/passwd and redirects to them. Expected: rejected with a validation error; only allowed domains and schemes accepted.
API8: Security Misconfiguration
- Verbose errors with stack traces, SQL or file paths (send malformed input and read the 500 body).
- Missing HTTPS or HSTS; old TLS versions.
- CORS reflecting any origin with credentials.
- Default credentials on admin consoles; debug endpoints enabled (
/actuator,/debug,/swaggerin production when not intended). - Unnecessary methods enabled (TRACE).
- Sensitive responses cacheable (
Cache-Controlmissingno-store).
The practice API returns structured errors without stack traces, even for malformed JSON:
https://sqatools.in/wp-json/sqa-api/v1/validate/usercurl -i \
-X POST \
-H "Content-Type: application/json" \
-d '{"name": "Asha", ' \
"https://sqatools.in/wp-json/sqa-api/v1/validate/user"API9: Improper Inventory Management
Companies forget APIs: /v1/ still running after /v2/ launched, a staging server with real data exposed to the internet, a debug endpoint added for one release.
Tests: compare the API documentation with what’s actually deployed; try older versions of secured endpoints; check that non-production environments don’t contain real customer data and aren’t publicly reachable; keep an up-to-date API inventory (OpenAPI files per service).
API10: Unsafe Consumption of APIs
Your API trusts data from third-party APIs (address lookup, payment gateway, partner catalogue) more than user input. Attackers compromise or imitate the third party instead.
Tests: mock the third-party API to return malicious values (script tags, SQL strings, huge payloads, redirects, timeouts) and check your API validates and handles them; verify webhook signatures; ensure calls to partners use HTTPS and certificate validation.
Injection Testing (Still Important)
Injection isn’t a separate item in the 2023 API list, but it’s still a must-test. Send these in every text field and parameter, and expect them to be stored or rejected as plain text, never executed:
| Type | Sample payload | Bad sign |
|---|---|---|
| SQL injection | ' OR '1'='1, 1; DROP TABLE users-- | SQL errors, extra records, 500 |
| NoSQL injection | {"$ne": null} in a login field | Login succeeds without a password |
| Cross-site scripting (stored) | <script>alert(1)</script> | Script runs when another user views the data |
| Command injection | ; ls -la, $(whoami) | Command output in the response |
| XML external entity (XXE) | <!DOCTYPE x [<!ENTITY e SYSTEM "file:///etc/passwd">]> | File contents in a SOAP/XML response |
The practice API’s scenario 101 stores SQL and HTML strings in an object as plain text; create one and read it back to see correct behaviour.
Tools for API Security Testing
- Postman / Playwright: your normal tools cover most BOLA, auth, validation and rate-limit tests.
- OWASP ZAP (free): automated API scans from an OpenAPI file; proxy to inspect traffic.
- Burp Suite: intercept and modify requests, Intruder for fuzzing ids and payloads.
- Schemathesis / RESTler: generate thousands of edge-case requests from OpenAPI.
- jwt.io-style decoders and jwt_tool: inspect and attack JWTs.
- Semgrep, Snyk, Dependabot: code and dependency scanning (developer side).
A Security Smoke Suite in Playwright
import { test, expect } from '@playwright/test';
const BASE = 'https://sqatools.in/wp-json/sqa-api/v1';
test('protected endpoints refuse anonymous calls', async ({ request }) => {
for (const path of ['/basic/profile', '/apikey/profile', '/auth/me', '/token/objects']) {
expect((await request.get(`${BASE}${path}`)).status(), path).toBe(401);
}
});
test('responses expose only schema fields', async ({ request }) => {
const user = (await (await request.get(`${BASE}/users/1`)).json()).data;
expect(Object.keys(user).sort()).toEqual(
['active', 'age', 'city', 'created_at', 'email', 'id', 'name', 'role', 'username']);
});
test('malformed input gives a clean 4xx without internals', async ({ request }) => {
const res = await request.post(`${BASE}/validate/user`, {
headers: { 'Content-Type': 'application/json' }, data: '{"name": "Asha", ',
});
expect(res.status()).toBe(400);
const text = await res.text();
for (const leak of ['Stack trace', 'Exception', '.php', 'SQL', 'wp-includes']) expect(text).not.toContain(leak);
});
test('injection strings are stored as plain text', async ({ request }) => {
const payload = `' OR '1'='1 <script>alert(1)</script>`;
const res = await request.post(`${BASE}/objects`, { data: { name: payload, ttl: 30 } });
expect(res.status()).toBe(201);
expect((await res.json()).name).toBe(payload);
});
test('rate limit kicks in with Retry-After', async ({ request }) => {
let last;
for (let i = 0; i < 6; i++) last = await request.get(`${BASE}/rate-limit`);
expect(last!.status()).toBe(429);
expect(last!.headers()['retry-after']).toBeTruthy();
});
Note the rate-limit test shares a per-IP counter, so don’t run it in parallel with itself.
Interview Questions: API Security Testing
What is the OWASP API Security Top 10?
A list of the most critical API security risks published by OWASP. The 2023 edition is: BOLA, Broken Authentication, Broken Object Property Level Authorization, Unrestricted Resource Consumption, Broken Function Level Authorization, Unrestricted Access to Sensitive Business Flows, SSRF, Security Misconfiguration, Improper Inventory Management and Unsafe Consumption of APIs.
What is the most common API vulnerability?
Broken Object Level Authorization (BOLA/IDOR): the API doesn’t check that the requested object belongs to the caller, so changing an id exposes or modifies other users’ data.
How do you test an API for SQL injection?
Send SQL meta-characters and payloads such as a single quote or ‘ OR ‘1’=’1 in every parameter, header and body field. Look for 500 errors, SQL error messages, extra data or behaviour changes. A secure API returns a validation error or treats the input as plain text.
What is rate limiting and how do you test it?
Rate limiting caps the number of requests a client can make in a time window. Send requests past the documented limit and verify 429 Too Many Requests with Retry-After and rate-limit headers, and that the limit resets after the window.
What is excessive data exposure?
When an API returns more data than the client needs, relying on the UI to hide it, for example password hashes or other users’ emails in a response. Testers inspect raw responses and validate them against a strict schema.
What is SSRF?
Server-Side Request Forgery: an API that fetches a user-supplied URL can be tricked into calling internal services or cloud metadata endpoints. Test by supplying internal addresses and verifying they’re rejected.
Which tools do you use for API security testing?
Postman or Playwright for functional security checks, OWASP ZAP and Burp Suite for interception and scanning, Schemathesis for fuzzing from OpenAPI, and JWT tools for token analysis, always within authorised environments.
What should an error response never contain?
Stack traces, SQL queries, file paths, framework or server versions, internal hostnames, secrets or tokens. It should contain a clear error code and safe message.
What is mass assignment?
A vulnerability where an API automatically binds client-provided fields to internal models, letting attackers set privileged fields such as role or balance. It’s part of OWASP API3.
How is API security testing different from web UI security testing?
APIs expose raw data and actions directly without UI restrictions, so testers focus on authorization per object and function, token handling, input validation, rate limits and data exposure in responses, rather than mainly on browser issues.