API scan
APIs deserve their own scan type because their attack surface is shaped differently: no crawler can guess which POST bodies an endpoint accepts, what valid auth looks like, or which headers are required. Pentestas solves this by letting you feed it the spec.
Supported input
- OpenAPI 3.x (
.yamlor.json) - OpenAPI 2.0 / Swagger
- Postman collection v2.1 β including environment variables
- GraphQL schema (
.graphql/ SDL) or live introspection - Manual entry β just a root URL; Pentestas does its best by fuzzing common API paths
Upload via New scan β API β Upload spec, or POST to /api/scans/upload-spec. See Scans API.
What it checks
| Class | Notes |
|---|---|
| BFLA (Broken Function-Level Authorization) | Tries PUT/PATCH/DELETE on GET-only paths to find missing verb checks. |
| IDOR | Varies {id} in paths with adjacent + predictable + off-by-one values; flags unexpected 200s. |
| Mass assignment | Submits extra fields like is_admin=true, role=admin, tenant_id=<other> and watches for silent acceptance. |
| Rate limiting | Measures 5Γ, 10Γ, 50Γ burst behaviour; flags any endpoint that doesn't throttle auth/checkout. |
| Auth bypass | Missing Authorization β still 200. Wrong JWT β still 200. Expired token β still 200. |
| JWT weaknesses | alg=none, low-entropy secret, JWK header injection, algorithm confusion (RS/HS). |
| Method scanning | OPTIONS reveals methods the docs don't. Finds unintended verbs. |
| GraphQL introspection | Schema dump via __schema, even when the docs say it's disabled. |
| GraphQL DoS | Recursive queries, deep batching, alias amplification. |
| Response intelligence | Large payloads β likely lists; look for hidden fields (password_hash, secret, internal_notes). |
| NoSQL injection | MongoDB-style $ne, $gt, $regex operators in JSON bodies. |
Authenticated API scans
Three auth models are supported:
1. Static bearer
{
"target_url": "https://api.example.com",
"scan_types": ["api"],
"config": {
"custom_headers": {"Authorization": "Bearer eyJ..."}
}
}
Valid for the duration of the scan. If the token expires mid-run, the scan fails over to unauthenticated probes.
2. OAuth 2.0 refresh token
{
"config": {
"oauth_refresh": {
"token_url": "https://auth.example.com/oauth/token",
"refresh_token": "rt_abc...",
"client_id": "pentestas-scanner",
"client_secret": "..."
}
}
}
Pentestas mints a fresh access token at scan-start and refreshes mid-run if the token expires. Long scans keep working even if access tokens live 5 minutes.
3. API key
{
"config": {
"custom_headers": {"X-API-Key": "sk_live_..."}
}
}
Same as static bearer, just a different header name.
Use a low-privilege test account, not your admin token. Pentestas will try authenticated probes in parallel; an admin token makes the blast radius unnecessarily large.
GraphQL specifics
Point the scan at /graphql (or whatever the endpoint is). Pentestas:
- Attempts schema introspection. If it fails, tries field-suggestion oracles to reconstruct the schema.
- Generates per-query + per-mutation probes using the schema.
- Fires authorization tests on every mutation.
- Tests for DoS via recursion, batching, and alias amplification.
- Tests for information disclosure via error messages.
gRPC
Upload a .proto file + endpoint URL. Pentestas generates reflection probes + message-level fuzz tests. Runs over gRPC-web for browser-facing services; over pure gRPC (HTTP/2) otherwise.
Output
Same finding shape as web scans, with API-specific enrichment:
- Endpoint β
POST /v2/users/{id}. - Body schema β if uploaded, the exact body that triggered.
- Reproduction β full
curlcommand you can paste into a terminal.
Pitfalls
- Rate-limiting chaos β if your API aggressively rate-limits, scans take longer. Increase the budget or whitelist the Pentestas scanner IPs (
scan-ips.pentestas.comreturns the current set). Better: run the scan from a local agent so it originates inside your network. - Multi-tenant APIs β supply the tenant ID in the spec's examples so Pentestas scopes probes to your test tenant. Cross-tenant probes don't happen by design.
- Pagination-only listings β if an endpoint returns a cursor in a JSON
nextfield, Pentestas will chase it up to 10 pages. If you need deeper, upload a spec withpagination: max_pages: 100.
See also
- Authenticated scans
- Webhooks β wire scan completion into your CI pipeline
- Scans API β full HTTP reference