1. What Is It?
Improper Inventory Management happens when an API exposes endpoints that are not properly tracked, documented, or maintained.
These endpoints often include legacy versions, deprecated routes, hidden features, or internal tools that remain accessible even after newer and more secure implementations are introduced.
The critical issue is not just that these endpoints exist — but that they are forgotten, inconsistent, or weaker than the main API surface.
2. Why It Matters
- Legacy endpoints often have weaker or outdated security
- Undocumented APIs bypass normal review processes
- Attackers actively search for forgotten routes
- Security fixes are applied to new versions, not old ones
OWASP classifies this risk because modern systems evolve quickly, but old endpoints are rarely removed. These forgotten surfaces often become the weakest entry point into an otherwise secure system.
Read the OWASP Definition3. How It Happens (Technical)
This issue appears when API versions, routes, or services are not properly tracked and maintained over time.
# secure (v2)
@app.get("/api/v2/admin/reports")
def reports_v2(claims):
if claims["role"] != "admin":
raise HTTPException(status_code=403)
return {"status": "restricted"}# vulnerable (v1 legacy)
@app.get("/api/v1/admin/reports")
def reports_v1(claims):
return {"export": "full data", "flag": FLAG}The same functionality exists in two places, but only the new version enforces proper authorization.
Key concept: attackers do not break secure endpoints. They find older, weaker ones.
Attacker’s Perspective
- Enumerate versions: /v1, /v2, /beta
- Search for undocumented endpoints
- Compare behavior across versions
- Target the weakest implementation
4. Real-World Example
This benchmark models a system where a secure API version exists, but an older version remains exposed with weaker controls.
GET /api/v2/admin/reports→ correctly restrictedGET /api/v1/admin/reports→ legacy, weak
# v2 (secure)
if claims.get("role") != "admin":
raise HTTPException(status_code=403)# v1 (vulnerable)
return {
"version": "v1",
"export": "legacy full export",
"flag": FLAG,
}Even though the new version is secure, the old version exposes full admin data to non-admin users.
Attack flow:
- Login as support user
- Test v2 → blocked
- Test v1 → succeeds
- Extract sensitive data
Common Variations
- Deprecated API versions still active
- Shadow or undocumented endpoints
- Internal tools exposed externally
- Test/debug routes left enabled
5. How To Prevent
- Maintain a complete API inventory
- Remove deprecated endpoints aggressively
- Ensure security parity across versions
- Monitor and audit exposed routes regularly
GOOD:
Only /v2 exists
BAD:
v1 (weak) + v2 (secure) both exposedIf an endpoint exists, it must be secured — even if it is deprecated.
6. Detection Tips (Scanner Perspective)
- Enumerate API versions automatically
- Compare responses across versions
- Test undocumented endpoints
- Look for inconsistent authorization behavior
7. Final Takeaway
API9 is about exposure through forgotten surfaces.
You are not only securing your API — you are securing every version of it.