API Security Evaluation: Testing REST APIs Against Security Requirements
Theory
Prerequisites
- STE-K002: Test Case Design
- PEN-K009: Business Logic & API (recommended)
Why This Lesson Matters
Modern applications are APIs first. The web UI is often just a thin wrapper around REST or GraphQL endpoints that expose every data operation the business logic supports. API security evaluation tests whether those endpoints enforce the same controls that the UI presents. The answer is often: they do not.
1. API Discovery
Before evaluating an API, you must know what it exposes.
Discovery sources (in priority order):
1. OpenAPI / Swagger spec: /swagger.json, /openapi.json, /v2/api-docs
2. API documentation portal: /docs, /api/docs, /developer
3. JavaScript bundle analysis: grep JS files for fetch/axios calls
4. Burp Suite traffic capture: browse the app while Burp intercepts
Tools:
kiterunner — wordlist-based API endpoint discovery
arjun — discover hidden parameters on known endpoints
# Extract all endpoints from OpenAPI spec
curl -s https://api.corp.local/openapi.json |
jq '.paths | keys[]' | sort
# Check for exposed secrets in the spec
curl -s https://api.corp.local/openapi.json |
grep -iE "api_key|secret|token|password|bearer|Authorization"
# Kiterunner for endpoints not in spec
kr scan https://api.corp.local -w routes-large.kite
2. API Authentication Evaluation
2.1 Missing Authentication
Control: All API endpoints handling user data shall require authentication.
Test procedure:
For each endpoint in scope:
Remove the Authorization header
Send the request
Expected: 401 Unauthorized
FAIL: 200 OK with data
# Automated check
while IFS= read -r endpoint; do
code=$(curl -s -o /dev/null -w "%{http_code}"
"https://api.corp.local$endpoint")
echo "$code $endpoint"
done < api_endpoints.txt | grep "^200" # 200 without auth = finding
2.2 Token Scope Enforcement
Control: API tokens shall only permit access to resources within their
authorised scope.
Test cases:
TC-API-003: Token with scope "read:profile" → GET /api/profile → 200 (positive)
TC-API-004: Token with scope "read:profile" → POST /api/profile → 403 (write blocked)
TC-API-005: Token with scope "read:profile" → GET /api/admin → 403 (scope blocked)
TC-API-006: Token with scope "read:profile" → GET /api/users (all) → 403 (scope blocked)
3. API Information Exposure
3.1 Hardcoded Credentials in Spec
Control: API specifications shall not contain credentials, API keys, or secrets.
Test procedure:
Download the OpenAPI/Swagger specification
Search for credential patterns:
- Bearer tokens in example headers
- API keys in example parameters
- Passwords in example request bodies
- Internal hostnames or IP addresses in server URLs
Patterns to check:
grep -iE "bearer [a-zA-Z0-9_.-]+" spec.json
grep -iE "api.?key.*[:=]['"]?[A-Za-z0-9]{16,}" spec.json
grep -iE "password|passwd|secret" spec.json
grep -iE "10.[0-9]+.[0-9]+.[0-9]+|192.168" spec.json # internal IPs
3.2 Excessive Data Exposure
Control: API responses shall not return fields not required by the consuming client.
Test procedure:
Step 1: Request your own user profile
GET /api/users/me → {"id": 1, "name": "Alice", "email": "[email protected]"}
Step 2: Compare response against documented fields
Step 3: Identify any undocumented or unexpected fields:
{"id": 1, "name": "Alice", "email": "[email protected]",
"password_hash": "$2b$12$...", ← FAIL
"internal_user_id": "usr_48291", ← FAIL
"is_admin": false} ← Note: modifiable?
Finding: API response contains password hash field (password_hash)
→ Even though hashed, exposing this field violates minimal disclosure principle
→ Enables offline cracking attempts
3.3 Verbose Error Messages
Test procedure:
Submit malformed requests to each endpoint and inspect error responses:
- Invalid JSON body → should return generic 400
- Missing required field → should return generic 400
- Invalid ID format → should return generic 400
FAIL examples:
"MongoError: Cast to ObjectId failed for value 'x' at path '_id'" → reveals DB type
Stack trace containing file paths → reveals internal structure
"User 'root'@'localhost' denied access" → reveals DB config details
4. API Rate Limiting Evaluation
Control: The API shall enforce rate limiting of 100 requests/minute per token.
Test procedure:
Step 1: Send 110 requests with the same token in 60 seconds
Step 2: Monitor response codes
Expected: requests 1-100: 200 OK; requests 101-110: 429 Too Many Requests
FAIL: all 110 requests return 200 (no rate limiting)
Tooling:
hey -n 110 -c 10 -H "Authorization: Bearer TOKEN" https://api.corp.local/endpoint
# -n = total requests; -c = concurrent
5. Common Mistakes
Mistake 1: Only testing authenticated endpoints. Unauthenticated API endpoints (public pricing, health checks, documentation) may still leak internal information. Test all discovered endpoints, not only those that require auth.
Mistake 2: Not comparing response to the documented schema. Excessive data exposure is invisible unless you know what the API is supposed to return. Always compare actual responses against the documented schema.
6. Practice Exercises
-
An OpenAPI spec includes:
"example": {"Authorization": "Bearer sk-prod-a3f9b2c1"}. Write the STE finding with control reference, test procedure, and remediation. -
GET /api/users/mereturns:{"name":"Alice","email":"[email protected]","password_hash":"$2b$12$abc...","admin":false}. Which two control violations are present? Write findings for each. -
Rate limiting: you send 200 requests in 60 seconds. Requests 1-200 all return 200. After 60 seconds, requests continue to return 200. Is rate limiting absent, misconfigured, or working? How do you determine which?
7. Lab
Assessment mode: flag
challenge_spec_id: 186 — Swagger exposed secrets
Task: 1. Find the exposed API documentation endpoint 2. Locate a hardcoded credential in the spec examples 3. Use the credential to call a privileged API endpoint 4. The response from the privileged endpoint contains the flag
8. Framework Alignment
| Framework | Role | Competency | Confidence |
|---|---|---|---|
| CCSSF-STE | Security Testing & Evaluation | API security evaluation | High |
| CCSSF-PEN | Penetration Tester | API reconnaissance and testing | High |
| NICE 2.2.0 | Security Testing | K0009 — API security | High |
9. Further Reading
- OWASP API Security Top 10 — https://owasp.org/API-Security/
- kiterunner — https://github.com/assetnote/kiterunner — API endpoint discovery
- arjun — https://github.com/s0md3v/Arjun — Hidden parameter discovery
Learning Objectives
["Discover API endpoints from an OpenAPI specification and by scanning traffic, then test five endpoints for missing authentication by removing the Authorization header", "Identify excessive data exposure by comparing an API response against the documented schema and write a finding for each undocumented field returned", "Find a hardcoded credential in an OpenAPI specification example, use it to call a privileged endpoint, and document the finding with CVSS score and remediation"]
Lesson Outline
Prerequisites → Why this matters → API discovery (sources, kiterunner, spec extraction) → Authentication evaluation (missing auth, scope enforcement) → Information exposure (hardcoded creds in spec, excessive data, verbose errors) → Rate limiting evaluation → Common mistakes → Practice exercises → Lab (flag, spec 186) → Framework alignment → Further reading
Challenge Lab
Reinforce your learning with a hands-on generated challenge based on this card's competency.