A collection of lightweight, modular scanners for auditing REST, GraphQL, WebSocket, and gRPC API security. Each tool is self-contained and designed for black-box reconnaissance during authorised penetration tests.
# Clone the repository
git clone https://github.com/ridhinva/API-Security-Toolkit.git
cd API-Security-Toolkit
# Install base dependency (shared by rest_api_scanner & graphql_scanner)
pip install requests
# Optional dependencies per tool:
pip install websocket-client # websocket_scanner
pip install grpcio-tools # grpc_scannerAll tools are standalone Python 3 scripts — no framework, no config files.
Probes common REST API endpoints and tests authentication with default credentials.
# Single target
python rest_api_scanner.py -u https://target.example.com
# Batch scan from file
python rest_api_scanner.py -f targets.txt
# Tweak concurrency / timeout
python rest_api_scanner.py -u https://target.example.com -t 20 --timeout 3
# Skip auth endpoint testing
python rest_api_scanner.py -u https://target.example.com --no-auth| Phase | What happens |
|---|---|
| Endpoint probing | Sends concurrent GET requests to 30+ common REST paths (/api, /api/v1, /swagger.json, /openapi.json, /health, /admin, /users, etc.). Responses are classified by HTTP status code: 2xx/3xx = ACCESSIBLE, 4xx/5xx = HIDDEN. |
| Auth endpoint testing | For each of 20+ known auth/identity endpoints (/login, /api/auth, /oauth/token, /signup, etc.), the scanner POSTs 12 default credential pairs (admin:admin, admin:password, test:test, guest:guest, etc.). If any pair returns a 2xx or a redirect, it is flagged as [AUTH] [WEAK_CRED]. |
| Result output | Findings are printed with structured [ENDPOINT], [ACCESSIBLE], and [AUTH] tags for easy grepping / post-processing. A summary line shows accessible vs. hidden vs. error counts. |
- ACCESSIBLE — HTTP 2xx or 3xx response from the endpoint.
- HIDDEN — HTTP 401, 403, 404, 405, or 5xx (suggests the endpoint may exist but is protected or returns a generic error).
- WEAK_CRED — Default/guessable credentials successfully authenticated against an auth endpoint.
- CONN_REFUSED / TIMEOUT — Network-level issues or WAF blocking.
Discovers exposed GraphQL endpoints and attempts schema introspection to reveal the full API surface.
# Single target
python graphql_scanner.py -u https://target.example.com
# Batch scan
python graphql_scanner.py -f targets.txt
# Adjust timeout
python graphql_scanner.py -u https://target.example.com --timeout 10| Phase | What happens |
|---|---|
| Endpoint discovery | Probes 14 common GraphQL URL patterns (/graphql, /api/graphql, /v1/graphql, /gql, /query, /graphiql, /playground, etc.) using both GET and POST with {"query": "{ __typename }"}. The scanner classifies each response by checking for JSON with GraphQL keywords ("data", "errors", "__typename") or GraphiQL HTML markers. |
| Introspection query | When a GraphQL endpoint is detected, the scanner sends the standard __schema introspection query to enumerate all types, queries, mutations, subscriptions, and directives. |
| Schema analysis | The introspection response is parsed to count schema types by kind (OBJECT, INPUT_OBJECT, ENUM, UNION, INTERFACE, SCALAR). Internal __ types are filtered out. The query/mutation/subscription root types are reported, along with the full list of user-defined type names (up to 50). |
- DETECTED — The endpoint responds with JSON containing GraphQL structure or HTML containing "graphiql"/"graphql".
- INTROSPECTABLE YES — The introspection query succeeded and returned schema data. A large type count (>50 types) suggests a complex surface with more potential attack vectors.
- INTROSPECTABLE NO — Introspection is disabled (server returned an error or empty schema), but the endpoint is still reachable.
Framework for testing WebSocket security: Cross-Site WebSocket Hijacking (CSWSH), message injection, and Origin header bypass.
# Basic scan
python websocket_scanner.py -u wss://target.example.com/ws
# With authentication header
python websocket_scanner.py -u wss://target.example.com/ws \\
--header "Authorization: Bearer <token>"
# Custom CSWSH origin testing
python websocket_scanner.py -u wss://target.example.com/ws --origin "null"
# Message injection test
python websocket_scanner.py -u wss://target.example.com/ws \\
--payload '{"action":"subscribe","channel":"admin"}'
# Batch scan
python websocket_scanner.py -f targets.txt| Technique | Methodology |
|---|---|
| CSWSH detection | Opens a WebSocket connection from a cross-origin context (simulated via custom Origin header). If the handshake succeeds without requiring authentication cookies, the endpoint is vulnerable to CSWSH. The scanner tests with: (1) the real target origin, (2) Origin: null, (3) spoofed subdomain origins, and (4) missing Origin. |
| Message injection | After connecting, the scanner sends malformed, oversized, or unexpected JSON payloads and monitors for error messages, stack traces, or anomalous server behavior that indicates injection points in the message-processing pipeline. |
| Origin bypass | Tests common Origin validation flaws: null origin, case-mutated origins (EXAMPLE.COM → example.com), subdomain permutations, and origin reflection (the server trusts its own origin value sent back). |
Note: The websocket_scanner is a stub that prints methodology and usage.
A full implementation requires the websocket-client package.
Framework for testing gRPC service security: reflection enumeration, service fingerprinting, and TLS transport checks.
# Basic scan
python grpc_scanner.py -u target.example.com:50051
# Plaintext (no TLS)
python grpc_scanner.py -u target.example.com:50051 --insecure
# Custom service name brute-force
python grpc_scanner.py -u target.example.com:50051 \\
--services-file my_services.txt
# Batch scan
python grpc_scanner.py -f targets.txt| Technique | Methodology |
|---|---|
| Reflection enumeration | Attempts a gRPC connection and queries the standard reflection service (grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo). If reflection is enabled, the full service and method tree is returned — including internal debug RPCs that should not be exposed to clients. |
| Service enumeration | If reflection is disabled, attempts a brute-force of common gRPC service names (derived from protobuf conventions). Sends empty/uninitialized requests and analyses the gRPC status code (UNIMPLEMENTED, OK, INVALID_ARGUMENT) to infer which services exist. |
| TLS check | Determines whether the server accepts TLS connections, plaintext connections, or both. A server that accepts plaintext gRPC (without TLS) is vulnerable to man-in-the-middle attacks. |
Note: The grpc_scanner is a stub that prints methodology and usage.
A full implementation requires the grpcio-tools package.
All tools follow a consistent tag-based output format for easy parsing:
[TAG] field1 [TAG] field2 [TAG] field3 detail
Common tags:
| Tag | Meaning |
|---|---|
[ENDPOINT] |
The URL path or endpoint being tested |
[ACCESSIBLE] |
YES/NO — whether the endpoint responded with 2xx/3xx |
[AUTH] |
Authentication test result |
[SCHEMA] |
GraphQL introspection result |
[DETECTED] |
YES/NO — whether the service type was identified |
This toolkit is intended for authorised security assessments only. Unauthorised scanning of systems you do not own or have explicit permission to test is illegal.
MIT