Generic Sanitizer
No customer hardcodes. Collapses duplicate path segments, normalizes /vN /vN.00, trims trailing slashes. Toggle with --no-sanitize and refine with --rewrite "pat=>rep".
APIscan is an API vulnerability scanner that proactively identifies security risks by testing against the OWASP API Security Top 10 (2023). It uses your OpenAPI/Swagger specification to generate realistic attack payloads and detect issues such as Broken Object Level Authorization (BOLA), Broken Authentication, Excessive Data Exposure, and other critical API vulnerabilities. APIscan supports OAuth 2.0, Bearer, mTLS, and API key authentication, generates realistic requests, runs scans in parallel, and offers optional AI-assisted review.
No customer hardcodes. Collapses duplicate path segments, normalizes /vN /vN.00, trims trailing slashes. Toggle with --no-sanitize and refine with --rewrite "pat=>rep".
Universal header model: --flow token --token, --apikey --apikey-header, --extra-header, --headers-file. Spec examples/defaults are autoapplied too.
--ids-file to control path variables; fallback generator covers *id, code, uuid, email, date.
Improved requestBody sampling order and accurate JSON detection (application/json; charset=UTF-8).
New --verify-plan option to test planned requests and --success-codes to define acceptable responses.
--retry500 option for automatic retries on HTTP 5xx errors with field augmentation from error messages.
# 1) Install (Python 3.11+ recommended)
pip install -r requirements.txt
# 2) Run with a Swagger/OpenAPI file
python apiscan.py --url https://api.example.com \
--swagger openapi.json --flow token --token <BEARER>
# Optional: export variables template
python apiscan.py --url https://api.example.com \
--swagger openapi.json --export_vars vars_template.yml
Full OWASP API Security Top 10 (2023) coverage with 11 dedicated audit modules:
Multiple authentication flows with flexible configuration:
Advanced request generation from OpenAPI specs:
Comprehensive reporting capabilities:
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--flow token --token "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
--threads 5
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--apikey "your-api-key-here" --apikey-header "X-API-Key" \
--api1 --api2 --api5 # Test only specific vulnerabilities
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--flow client \
--client-id "your-client-id" \
--client-secret "your-client-secret" \
--token-url "https://auth.example.com/oauth/token" \
--scope "api.read api.write"
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--flow token --token "<JWT>" \
--plan-only
Generates apiscan-plan.csv with all planned requests without executing them.
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--flow token --token "<JWT>" \
--verify-plan --success-codes "200-299,304"
Tests all planned requests and expects success codes in 200-299 range or 304.
# ids.json content:
{
"userId": "12345",
"orderId": "67890",
"vehicleId": "abc123",
"postId": "post-001"
}
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--ids-file ids.json \
--flow token --token "<JWT>"
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--rewrite "/v2(?!\.)=>/v2.00" \
--rewrite "/alpha/beta/alpha=>/alpha/beta" \
--no-sanitize \
--flow token --token "<JWT>"
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--proxy http://127.0.0.1:8080 \
--insecure \
--debug \
--flow token --token "<JWT>"
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--dummy \
--flow token --token "<JWT>" \
--verify-plan
Uses generated dummy data for all request bodies and parameters.
# headers.json content:
{
"X-Custom-Header": "custom-value",
"X-Tenant-ID": "tenant-123",
"X-Request-ID": "req-456"
}
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--headers-file headers.json \
--flow token --token "<JWT>"
# Set environment variables first
export LLM_PROVIDER=openai_compat
export LLM_MODEL=gpt-4o-mini
export LLM_API_KEY=sk-...
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--flow token --token "<JWT>" \
--api11 # Run AI-assisted analysis
python apiscan.py --url https://api.example.com \
--swagger openapi.json \
--flow token --token "<JWT>" \
--retry500 3 # Retry up to 3 times on 5xx errors
python apiscan.py --url https://api.company.com \
--swagger enterprise-api.json \
--flow token --token "<JWT>" \
--threads 10 \
--proxy http://corporate-proxy:8080 \
--ids-file prod-ids.json \
--headers-file prod-headers.json \
--rewrite "/v1/=>/v1.00/" \
--retry500 3 \
--verify-plan \
--success-codes "200-299,302,304"
Tests for inadequate access controls on object endpoints using ID manipulation and privilege escalation attempts.
Assesses authentication mechanisms for weaknesses like credential stuffing, weak tokens, and flawed session management.
Checks if users can access or modify object properties they shouldn't have permissions for.
Tests for resource exhaustion attacks through large payloads, deep nesting, or excessive requests.
Verifies proper authorization checks for sensitive functions and administrative endpoints.
Assesses business logic vulnerabilities that could be exploited to manipulate workflows.
Tests for SSRF vulnerabilities where the API makes requests to internal or external resources.
Checks for security misconfigurations like verbose errors, insecure defaults, or missing security headers.
Assesses API inventory exposure including outdated versions, exposed debug endpoints, and deprecated APIs.
Tests for vulnerabilities when consuming third-party APIs, including data validation and trust boundaries.
Uses AI to identify complex security patterns and business logic flaws that traditional scanners might miss.
Symptoms: Timeouts, connection refused, SSL errors
Solutions: Check network connectivity, verify URL, use --insecure for self-signed certs, configure proxy with --proxy
Symptoms: 401 Unauthorized, 403 Forbidden responses
Solutions: Verify token validity, check auth flow configuration, ensure proper headers with --headers-file or --extra-header
Symptoms: 404 Not Found, wrong endpoints being called
Solutions: Use --no-sanitize to disable URL normalization, add --rewrite rules for path corrections, verify Swagger file accuracy
Symptoms: 400 Bad Request, 422 Unprocessable Entity
Solutions: Use --dummy for generated data, check request body schemas in Swagger, use --export_vars to create template
Symptoms: Slow scanning, timeouts
Solutions: Reduce --threads, use --apiX flags to run specific tests only
Symptoms: API11 errors, LLM connection issues
Solutions: Verify LLM environment variables (LLM_PROVIDER, LLM_MODEL, LLM_API_KEY), check API quotas, ensure network access to LLM provider
Individual vulnerability reports (api_*_report.html) and combined master report with detailed findings, risk levels, and remediation guidance.
apiscan-plan.csv (planned requests) and apiscan-verify.csv (verification results) for further analysis or integration with other tools.
Detailed execution logs in the log/ directory with timestamps, request/response data, and error information for debugging.
Real-time progress with colored status indicators, vulnerability counts, and summary statistics upon completion.
APISCAN works from an OpenAPI/Swagger specification to plan and verify calls.
If you already have a Swagger/OpenAPI file (e.g., openapi.json or swagger.yaml), you can use it directly with --swagger.
If you only have a Postman collection, convert it first:
*.postman_collection.json).--swagger.# Convert Postman -> Swagger/OpenAPI (see repo for options)
python postman-to-swagger.py --input ./MyCollection.postman_collection.json --output ./openapi.json
# Then run APISCAN using the converted spec
python apiscan.py --url https://api.example.com --swagger ./openapi.json --plan-only --verify-plan
Repository: perrym/apiscanner
Medium: APISCAN a practical approach
Contact: pamsniffer@gmail.com