API Endpoint Enumeration
API endpoint enumeration maps the attack surface of REST APIs, GraphQL interfaces, and OpenAPI-documented services. APIs frequently have weaker input validation than frontend forms, expose more functionality than the UI presents, and often lack the same access control enforcement. Run this after content discovery confirms an API path exists, or when fingerprinting reveals a framework that typically exposes APIs.
OpenAPI and Swagger Discovery
Many frameworks auto-generate API documentation at predictable paths. Check these before doing anything else:
404 /api/docs 200 /swagger-ui.html 200 /swagger.json 404 /openapi.json
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allows insecure SSL/TLS connections, skipping certificate verification. |
| -I | Sends a HEAD request, fetching only response headers. |
| $TARGET_IP | Placeholder for the target host IP address. |
| $PORT | Placeholder for the target port number. |
A 200 on swagger.json or openapi.json gives you the complete API definition including all endpoints, parameters, authentication requirements, and data models. Download it and parse it for targets:
"/api/v1/users": {
"/api/v1/users/{id}": {
"/api/v1/admin/users": {
"/api/v1/orders": {
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allows insecure SSL/TLS connections, skipping certificate verification. |
| http://$TARGET_IP:$PORT/swagger.json | Target URL with variable host and port to fetch the Swagger API spec. |
| -m json.tool | Runs Python's built-in JSON pretty-printer module to format output. |
| -E | Enables extended regular expression syntax in grep pattern matching. |
| "/(api|v[0-9])' | Regex pattern to filter lines containing API or versioned route paths. |
/api/v1/users
/api/v1/users/{id}
/api/v1/admin/users
/api/v1/orders
/api/v1/products
Explain command
| -s | Silent mode; suppresses progress and error output. |
| -k | Allows insecure SSL/TLS connections, skipping cert validation. |
| http://$TARGET_IP:$PORT/swagger.json | Target URL with variable host and port to fetch Swagger API spec. |
REST API Endpoint Bruteforce
When no documentation is available, bruteforce common API paths with a dedicated wordlist:
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt | Wordlist file path used for fuzzing input. |
| -u http://$TARGET_IP:$PORT/api/FUZZ | Target URL with FUZZ keyword marking the injection point. |
| $TARGET_IP:$PORT | Variable placeholders for the target host IP and port number. |
| -mc 200,201,204,301,302,401,403 | Match only responses with these specific HTTP status codes. |
| -o api_endpoints.json | Write output results to the specified file in JSON format. |
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt | Wordlist file path used for fuzzing input. |
| -u http://$TARGET_IP:$PORT/api/v1/FUZZ | Target URL with FUZZ keyword marking the injection point. |
| $TARGET_IP:$PORT | Variable placeholders for the target host IP and port number. |
| -mc 200,201,204,301,302,401,403 | Match only responses with these specific HTTP status codes. |
Test common API version prefixes when you don't know the versioning scheme:
404 /v1/users 200 /v2/users 404 /v3/users 401 /api/v1/users
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allow insecure TLS connections, skipping certificate verification. |
| -I | Send HTTP HEAD request and show response headers only. |
| $TARGET_IP:$PORT | Target host IP and port number for the HTTP request. |
HTTP Method Testing
REST APIs often have different behavior per method. Test GET, POST, PUT, PATCH, and DELETE on discovered endpoints — some may be accessible with methods the application doesn't use in the UI:
GET: 200 POST: 201 PUT: 405 PATCH: 403 DELETE: 403 OPTIONS: 200
Explain command
| -s | Silent mode, suppresses progress meter and error messages. |
| -k | Allow insecure TLS connections, skipping certificate verification. |
| -X $method | Specifies the HTTP method to use for the request. |
| http://$TARGET_IP:$PORT/api/v1/users | Target URL with variable host and port for the API endpoint. |
| -H 'Content-Type: application/json' | Sets the Content-Type request header to application/json. |
| -o /dev/null | Discards the response body by writing output to /dev/null. |
| -w '%{http_code}' | Prints the HTTP response status code after the request completes. |
A 403 on DELETE or PATCH where GET returns 200 suggests the endpoint exists but is access-controlled. These are candidates for authorization bypass testing and IDOR testing.
GraphQL Enumeration
GraphQL exposes a single endpoint that handles all queries. Detect it and run introspection to dump the full schema:
200 /graphql 404 /api/graphql
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allow insecure TLS connections, skipping certificate verification. |
| -I | Send HEAD request to fetch HTTP response headers only. |
| $TARGET_IP | Placeholder for the target host IP address. |
| $PORT | Placeholder for the target port number. |
| /graphql /api/graphql /graphiql /graphql/console /v1/graphql | Common GraphQL endpoint paths iterated over in the loop. |
"name": "Query" "name": "User" "name": "Order" "name": "Admin"
Explain command
| -s | Silent mode; suppresses progress and error output. |
| -k | Allow insecure SSL connections, skipping certificate verification. |
| -X POST | Specifies HTTP POST as the request method. |
| http://$TARGET_IP:$PORT/graphql | Target GraphQL endpoint using variable host and port. |
| -H 'Content-Type: application/json' | Sets request header to indicate JSON body payload. |
| -d '{"query":"{__schema{types{name}}}"}' | Sends GraphQL introspection query to enumerate schema types. |
| -m json.tool | Pipes output through Python's JSON pretty-printer module. |
| grep '"name"' | Filters output lines containing the 'name' field from schema types. |
Explain command
| -d | Enable detection mode to identify the GraphQL engine in use. |
| -t | Specify the target URL to fingerprint. |
| http://$TARGET_IP:$PORT/graphql | Target GraphQL endpoint with variable host and port. |
Introspection returning type names confirms GraphQL is active and introspection is enabled. Run a full introspection query to dump all queries, mutations, and field definitions. The presence of an Admin type or mutation is an immediate escalation target.
References
-
SecLists — API Wordlistsgithub.com/danielmiessler/SecLists/tree/master/Discovery/Web-Content/api (opens in new tab)
API endpoint wordlists for REST bruteforce
-
GraphQL fingerprinting and introspection tool
-
GraphQL — Introspectiongraphql.org/learn/introspection (opens in new tab)
Introspection query format and schema discovery
Was this helpful?
Your feedback helps improve this page.