While practicing API security labs, I came across a simple but important lesson about how attackers explore APIs.
Modern web applications rely heavily on APIs. When a user performs an action in the interface, the browser sends a request to the backend API.
For example, updating an email address might send a request like:
PATCH /api/user/wiener
This simply tells the server: update the user wiener.
When you intercept such a request during testing, you can start exploring the API structure by moving through the path hierarchy:
/api/user/wiener → specific user
/api/user → user resource
/api → base API
In this lab, requesting /api revealed the application's API documentation.
The documentation listed all available endpoints supported by the backend. One of them was:
DELETE /api/user/{username}
This endpoint allows deleting a user.
The website interface never exposed this functionality, but the API still supported it. Because the API did not enforce proper authorization, even a normal user could send:
DELETE /api/user/carlos
The server accepted the request and deleted the user carlos.
Key lesson:
In modern applications, the API is the real control layer. If security checks exist only in the UI and not in the API, attackers can bypass the interface and directly interact with backend functionality.
Simple API testing habit:
• Intercept API requests
• Understand the endpoint structure
• Explore higher-level paths like /api
• Look for exposed documentation
• Test additional HTTP methods
Sometimes exploitation doesn't require complex techniques — it simply requires discovering what the API already allows.
Top comments (1)
This is such an underrated point. Outdated or incomplete docs can absolutely be a security blind spot — seen it happen more than once.
One thing I’ve started doing: making the API itself self-documenting via OpenAPI, then using a tool to generate the external docs. It doesn’t fix everything, but it reduces drift.
I’ve also been experimenting with having an AI generate the initial draft of READMEs / API docs from raw code, then reviewing manually. Saves a ton of time and avoids the ‘I’ll write it later’ trap. Happy to share the approach if anyone’s curious.