Here are some steps for enumerating an API.

What/where is the API?

  • Scan server ports. Is it a REST API, gRPC, GraphQL, etc?
  • Look for /api path if web server is HTTP.
  • Look for an API subdomain, e.g. api.example.com.

What are its endpoints?

  • Look for API endpoints referenced in client (take a look at frontend HTML/JS or reverse engineer client binary).
  • Look for API schemas. Does the /api/ route provide anything?
  • Is the documentation endpoint exposed? Does it provide request & reply schemas? As a side note, if an API uses some kind of Swagger/OpenAPI UI library, look for related vulnerabilies.
    • /swagger/index.html
    • /openapi.json
  • Are there multiple versions of the API in production? Try to see if older APIs are vulnerable.
    • /api/v1: basic URL versioning
    • /api/<some-endpoint>/v1: per-route versioning
    • Versioning via HTTP header, e.g. X-Api-Version
  • Try to register as a user, use various site functionalities, and use Burp Suite to record & map out all the routes.
  • Try dirbust for API endpoints recursively (perhaps using OPTIONS if supported). You might have to make your own wordlist that suits the context of the API/service/company.

For each endpoint:

  • What are the parameters? Can you bruteforce for more hidden parameters? Can you try injecting key-values pairs (e.g., isAdmin=true that may be accidentally bound to server-side objects?
    • Is the server validating the values properly (type, range, format, etc)?
    • Are there conflicts between optional parameters? Does the server check them properly?
  • Are there subresources? e.g. /api/users/:user-id/paymentmethods
  • What are the allowed methods? Try OPTIONS or just try all methods one by one.
  • What kind of formats does it accept? JSON? url-form-encoded? Media (.mp4, .jpeg, etc)? Can you fiddle with the parsing process?
  • Does it use gzip compression? Can you crash the server with a gzip bomb?
  • Does API server have per-IP or per-user rate-limiting? Does it throttle properly?
  • Does the API authenticate via header (e.g. JWT) or session cookie? Does the server check for authorization properly? Try accessing the resource as a different identity.
  • Try messing with the Content-Type with and without changing the actual content. Does it trigger any error? Can this bypass schema (e.g., JSON schemas) checks? Does finding a new accepted format open up injection possibilities?