Improper Inventory Management
A home-energy app deprecated its 2023 API version but never took it out of production. An attacker with no token changes v2 to v1 in the URL and reads customer records the current version refuses, then walks the ids. You retire the version to 410 Gone.
What Is Improper Inventory Management?
Improper inventory management (OWASP API9:2023, previously called Improper Assets Management) is what happens when an organization loses track of what it has exposed: old API versions that were deprecated but never decommissioned, undocumented endpoints, and non-production or forgotten hosts that keep running with none of the controls the current version added. A security control only ever covers the endpoints you know are live, so a version left running outside your inventory is an attack surface you are not watching. The classic shape: the current version is put behind a new gateway or check, an older version predates it and is simply labelled deprecated in the docs, and because it is still deployed and routed it keeps answering, running the old, unguarded code. This exercise puts you on both sides. As Bob, an outside attacker with no account and no token, you probe Emberline's current home-energy accounts API and it correctly refuses you with 401; then you change a single URL segment from v2 to v1, the deprecated 2023 build, and the same unauthenticated request comes back 200 with a customer's name, email, and home address, because that version was never taken out of production and sits outside the auth gateway. Since it checks for no token at all, you walk the account ids and turn one leak into a bulk list of customers and where they live. As Alice, the platform engineer who owns the API gateway and version lifecycle, you get the monitoring alert, open the routing, see the current version mounted behind the gateway and the old one mounted straight past it, and ship the fix: retire the legacy version so every path under it returns 410 Gone and the unmaintained build comes out of production. The exercise closes with quiz questions on why deprecation in the docs is not retirement, why a secure current version does not cover an old one still serving, why 410 Gone is the right signal for a removed version, and why maintaining an inventory of every deployed version and host is the durable control.
What You'll Learn in Improper Inventory Management
- Recognize improper inventory management: old, undocumented, or non-production API versions and hosts left running and reachable, outside the controls the current version enforces
- Understand that a new control (an auth gateway, a check) only covers the versions mounted behind it, so an older version left in production serves the pre-control code to anyone
- See how changing one URL segment from the current version to a deprecated one reaches a forgotten build, and how an unauthenticated endpoint turns into bulk data exposure through simple enumeration
- Distinguish it from broken object level authorization (a missing per-record ownership check inside an authenticated endpoint) and from excessive data exposure (over-returning fields); here the whole version runs unauthenticated because it was never retired
- Apply the fix: retire unsupported versions so they return 410 Gone and come out of production, and maintain an inventory of every deployed version, environment, and host so nothing runs unwatched
Improper Inventory Management — Training Steps
-
An old version, still listed
Emberline is a home solar and energy app: customers link their panels and battery, and the app reads their account from Emberline's API. Today Bob is targeting Emberline. He has no account and no token; he just wants a list of customers and where they live, to sell on. He starts on Emberline's public developer docs to learn the API.
-
Deprecated, not gone
The docs describe two API versions. Bob reads how each one is labelled, and one label catches his eye.
-
Ask the current version
First Bob calls the current version the way the docs describe: he asks for one account by its id, using the example id from the reference. He has no token, so this is the unauthenticated case. If the gateway is doing its job, it should refuse him.
-
The gateway refuses
The current version did exactly what it should.
-
Change one segment
Bob sends the same request, still with no token, and changes only one thing: the version in the URL, from v2 to v1 , the deprecated build. Everything else is identical. If the old version is truly gone, this should reach nothing.
-
The forgotten version answers
The same request the gateway just refused came back with data.
-
Walk the accounts
One record is a warning. Because v1 asks for no token at all, nothing stops Bob from walking account ids. He keeps the version on v1 and changes the id to the next customer.
-
Every customer, at scale
Another id, another real customer.
-
Knowledge check
You just watched an attacker with no account read customer records by switching the version in the URL. Lock in why.
-
The alert lands
You own Emberline's API gateway and the lifecycle of every API version behind it. Overnight, monitoring flagged thousands of unauthenticated reads on the old /v1 accounts endpoint, from a single address, walking account ids in sequence. Security operations has emailed you.