APIs are the backbone of every SaaS product. They power your mobile app, enable partner integrations, serve your dashboard, and increasingly, expose functionality to AI agents and LLMs. They’re also your largest attack surface — and the one most likely to be undertested.
Our API penetration testing service uses the methodology described here to find the business logic flaws and authorisation gaps that automated scanners miss. See how we applied it in our API penetration testing case study for a fintech startup.
The OWASP API Security Top 10 exists for good reason: API vulnerabilities differ from traditional web application vulnerabilities in important ways. They often involve business logic flaws, broken object-level authorisation, and improper data exposure that standard vulnerability scanners entirely miss. This guide gives you the methodology, tooling, and context to test your APIs properly.
Why API Security Is Different
Traditional web application security focuses heavily on UI-level vulnerabilities — XSS, CSRF, clickjacking. APIs change the threat model:
- No UI — attackers interact directly with endpoints, bypassing any client-side validation
- Machine-to-machine — API keys and service accounts often have broad permissions
- High data density — a single API call can return hundreds of records
- Implicit trust — internal APIs between microservices often have no authentication at all
- Versioning complexity —
/v1/,/v2/,/beta/,/legacy/endpoints often have inconsistent security controls
The average SaaS company has 40–100+ API endpoints. Each is an entry point. Each needs to be tested.
The OWASP API Security Top 10 (2023)
API1:2023 — Broken Object Level Authorization (BOLA)
The most critical API vulnerability. An API returns data for object ID X — can an attacker change that ID to access another user’s object?
Vulnerable:
GET /api/v1/contracts/847 ← your contract
GET /api/v1/contracts/848 ← another customer's contract (if no ownership check)
How to test: Enumerate IDs, swap IDs between accounts, use UUIDs from one authenticated session in another.
Fix: For every API endpoint that returns or modifies data, verify that the authenticated user has permission to access that specific object — not just that they’re authenticated.
API2:2023 — Broken Authentication
API authentication issues differ from web app authentication:
- API keys hardcoded in mobile apps (extractable via reverse engineering)
- JWT tokens with
alg: noneaccepted - JWT tokens with weak signing secrets (crackable offline)
- Missing token expiry
- Bearer tokens transmitted over HTTP (logged by proxies)
- API keys with no scope restrictions (can perform any action)
Test vectors:
- Remove the Authorization header — does the endpoint still respond?
- Submit an expired JWT — is it accepted?
- Modify JWT claims (try
"role": "admin") — is the signature validated? - Try
{"alg": "none"}JWT attacks
API3:2023 — Broken Object Property Level Authorization (BOPLA)
An API might correctly restrict which objects you can access, but still let you access too many fields on those objects — or modify fields you shouldn’t be able to modify.
Mass assignment vulnerability:
// Request
PUT /api/users/profile
{"name": "Alice", "email": "alice@example.com", "role": "admin"}
// If the API binds all request properties to the user object:
// → user.role is now "admin"
Excessive data exposure:
// The UI shows only name and email
// But the API returns:
{
"name": "Alice",
"email": "alice@example.com",
"password_hash": "$2b$12$...",
"stripe_customer_id": "cus_xxx",
"internal_notes": "VIP customer, payment issues in Q1"
}
Fix: Explicitly define which fields are readable and writable per endpoint. Use DTOs (Data Transfer Objects) or response serialisers that only include intended fields.
API4:2023 — Unrestricted Resource Consumption
APIs without rate limiting or resource controls are vulnerable to:
- Denial of service (flood the endpoint, exhaust resources)
- Brute force (try millions of passwords against
/api/auth/login) - Data scraping (paginate through all records)
- Expensive operation abuse (trigger expensive computation repeatedly)
Test vectors:
- Remove rate limiting by rotating IPs or using distributed requests
- Submit extremely large payloads
- Trigger expensive operations in rapid succession (report generation, PDF export, bulk email)
API5:2023 — Broken Function Level Authorization
Users accessing admin-only functions. Typically discovered by:
- Fuzzing endpoints (try
/api/admin/users,/api/internal/config) - Changing request method (
GET /api/users→DELETE /api/users) - Accessing unpublished API endpoints from old documentation or JavaScript bundles
Test vectors:
- Enumerate endpoints from JavaScript bundles and mobile app binaries
- Try HTTP method tampering on all endpoints
- Use a non-admin account to call admin endpoints from the API documentation
API6:2023 — Unrestricted Access to Sensitive Business Flows
Business logic flaws specific to your application’s workflows:
- Bypassing payment steps in a checkout flow
- Applying promotional codes more than once
- Accessing content before a subscription is paid
- Race conditions in resource-limited flows (two requests simultaneously claim the last seat)
These cannot be found by automated scanners — they require understanding your application’s business logic.
API7:2023 — Server Side Request Forgery (SSRF)
As covered in the OWASP Top 10 section, SSRF in APIs is particularly dangerous because:
- SaaS APIs often have URL fetching functionality (webhook endpoints, URL preview, import from URL)
- Cloud metadata endpoints are reachable from application servers
- Internal service meshes are reachable from compromised application containers
API8:2023 — Security Misconfiguration
API-specific misconfigurations:
- CORS configured with
Access-Control-Allow-Origin: *andAccess-Control-Allow-Credentials: true(allows any site to make authenticated API requests) - HTTP methods not restricted (GET endpoint also accepts DELETE)
- Debug endpoints left enabled in production (
/api/debug/,/api/status/full) - Swagger/OpenAPI docs publicly accessible (helpful for attackers enumerating endpoints)
- Missing security headers
API9:2023 — Improper Inventory Management
- Old API versions still functional (v1 deprecated, v2 is current — but v1 might lack security controls added in v2)
- Undocumented internal APIs accessible from external networks
- Third-party APIs integrated without security review
API10:2023 — Unsafe Consumption of APIs
When your application integrates third-party APIs:
- Do you validate responses from third-party APIs before using the data?
- Can an attacker control a third-party API response to inject data into your system?
- Are third-party API keys scoped to minimum required permissions?
API Security Testing Methodology
Phase 1: Reconnaissance
Collect the API surface:
- API documentation — check for Swagger/OpenAPI at
/api/docs,/swagger.json,/openapi.yaml,/api-docs - JavaScript bundles — extract API endpoints from your application’s JS
- Mobile app reverse engineering — jadx (Android APK) or class-dump (iOS) to extract API calls
- Historical sources — Wayback Machine, Common Crawl, Google dorks (
site:api.yourapp.com) - Fuzzing — directory brute-forcing with API-specific wordlists
Tools:
- Burp Suite — intercept, replay, and modify all API traffic
- Postman — build and execute API collections
- mitmproxy — intercept mobile app traffic (install CA cert on test device)
- ffuf / feroxbuster — endpoint fuzzing
- gf (tomnomnom) — extract interesting patterns from JavaScript
Phase 2: Authentication Testing
JWT testing checklist:
# Decode JWT without verification
echo "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoidXNlciJ9.xxx" | \
cut -d'.' -f1,2 | base64 -d
# Try alg:none attack (craft a token with no signature)
# Try weak secret brute force
hashcat -a 0 -m 16500 jwt.txt wordlist.txt
# Test with jwt_tool
python3 jwt_tool.py <token> -t https://api.target.com/endpoint
API key testing:
- Rotate the key and test if old key is still valid
- Test if the key works from unexpected IPs
- Check if key appears in logs, error messages, or responses
- Test key scope — can a read-only key perform write operations?
Phase 3: Authorization Testing (BOLA/BOPLA)
This is the most important phase for SaaS APIs. Create two separate test accounts and test every endpoint:
# Account A session
ACCOUNT_A_TOKEN="eyJhbGc..."
ACCOUNT_A_RESOURCE_ID="workspace_123"
# Account B session
ACCOUNT_B_TOKEN="eyJhbGc..."
# Test BOLA: Can Account B access Account A's resource?
curl -H "Authorization: Bearer $ACCOUNT_B_TOKEN" \
https://api.target.com/v1/workspaces/$ACCOUNT_A_RESOURCE_ID
Document every endpoint and object type, and test every combination. Automate with a simple script that replays all Account A requests with Account B’s token.
Phase 4: Input Validation Testing
For every parameter, test:
# SQL injection
email=user@test.com' OR '1'='1
id=1; DROP TABLE users--
id=1 UNION SELECT username,password FROM users--
# NoSQL injection (MongoDB)
{"username": {"$gt": ""}}
{"username": {"$regex": ".*"}}
# GraphQL injection
query { user(id: "1\"; DROP TABLE users; --") { name } }
# Template injection
name={{7*7}}
name=${7*7}
name=<%= 7*7 %>
# Path traversal
filename=../../etc/passwd
filename=..%2F..%2Fetc%2Fpasswd
# SSRF
url=http://169.254.169.254/latest/meta-data/
url=http://internal-service.local/admin
Phase 5: Business Logic Testing
This requires understanding your application’s business rules:
- Map all multi-step workflows (signup, purchase, subscription, team invite)
- Try to skip steps or execute them out of order
- Test concurrent requests on resource-limited operations (race conditions)
- Test boundary conditions (apply a 100% discount code, submit negative quantities)
- Test state transitions — can you move an object to an invalid state?
Phase 6: Rate Limiting and DoS Testing
# Basic rate limit test with curl
for i in {1..100}; do
curl -s -o /dev/null -w "%{http_code}\n" \
-X POST https://api.target.com/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test@test.com","password":"wrong"}'
done
# More sophisticated with wrk or hey
hey -n 1000 -c 50 https://api.target.com/api/expensive-operation
Expected result: 429 responses after threshold is hit. If 200s continue indefinitely, rate limiting is absent.
Tools Reference
Essential Tools
| Tool | Category | Use Case |
|---|---|---|
| Burp Suite Pro | Proxy / scanner | Primary API testing platform |
| Postman | API client | Organise and replay test cases |
| jwt_tool | Auth testing | JWT attack toolkit |
| Arjun | Parameter discovery | Find hidden API parameters |
| kiterunner | Endpoint fuzzing | API-specific route brute-forcing |
| ffuf | General fuzzing | Fast endpoint and parameter fuzzing |
| Nuclei | Template scanner | API-specific vulnerability templates |
| mitmproxy | Proxy | Mobile app traffic interception |
GraphQL-Specific Tools
| Tool | Use Case |
|---|---|
| GraphQL Voyager | Visualise schema |
| InQL (Burp Extension) | GraphQL security testing |
| Clairvoyance | Schema introspection when disabled |
| BatchQL | Batch query abuse testing |
Building a Continuous API Security Programme
One-time testing is not enough — APIs change with every release. Build continuous security:
In Development
- Threat modelling for new API endpoints before implementation
- Security code review checklist for API handlers (auth check, input validation, output filtering)
- IDE plugins — Snyk, SonarLint
In CI/CD
# GitHub Actions — API security scanning
- name: Run API Security Scan
uses: 42crunch/api-security-audit-action@v3
with:
api-token: ${{ secrets.API_SECURITY_TOKEN }}
spec: openapi.yaml
fail-on-score: 75
- name: DAST API Testing
run: |
docker run -t owasp/zap2docker-stable zap-api-scan.py \
-t https://staging.api.yourapp.com/openapi.json \
-f openapi \
-r zap-report.html
In Production
- WAF with API-specific rules — AWS WAF, Cloudflare API Shield, Apigee
- API gateway rate limiting and authentication enforcement
- Anomaly detection — unusual access patterns, mass data access, off-hours admin activity
- API inventory management — know every API that exists, deprecate old versions
Periodic Penetration Testing
- Full API penetration test annually (or after major releases)
- Business logic review whenever significant new workflows are added
- Mobile app reverse engineering annually to check for hardcoded secrets
Checklist for SaaS Companies
Before launching a new API or major version:
Authentication & Authorisation
- Every endpoint requires authentication (except explicitly public ones)
- Object-level authorisation checked on every data access (not just route-level)
- JWTs validated for signature, expiry, and claims
- API keys scoped to minimum required permissions
Input & Output
- All inputs validated and sanitised server-side
- Parameterised queries used for all database operations
- Responses filtered to return only necessary fields
- Mass assignment protection in place
Rate Limiting & Performance
- Rate limiting on auth endpoints (login, password reset, signup)
- Rate limiting on resource-intensive endpoints
- Pagination enforced (no endpoint returns unlimited records)
Configuration
- CORS configured correctly (explicit allowed origins, not
*) - Security headers present
- Debug endpoints disabled in production
- API docs access-controlled if containing sensitive schema info
Monitoring
- Auth failures logged and alerted on
- BOLA attempts (unexpected 403s) logged
- Unusual access patterns trigger alerts
CyberneticsPlus provides comprehensive API penetration testing for SaaS platforms, covering REST, GraphQL, and gRPC APIs. Our testers use manual techniques to find business logic flaws and BOLA vulnerabilities that automated scanners miss. Read our fintech API security case study or get in touch to scope an assessment.