Chapter 07 of 12
Shadow and Zombie APIs
API9:2023 is about what is still answering that nobody remembers deploying, from an old version left running to a staging host with production data behind it.
This category is not about a flaw in an endpoint. It is about an endpoint nobody is thinking about, which is a different problem and often a larger one.
OWASP lists it as API9:2023 Improper Inventory Management, with CWE-1059 as its reference.
Two ways the list goes wrong
Zombies are versions and endpoints that were replaced and never switched off. Version 1 keeps answering after version 2 ships, carrying the code it had on the day it was superseded, which means it misses every fix since. An attacker comparing the two versions gets a map of what was fixed and a live host that still has it.
Shadows are endpoints that answer without being written down. A debug route, an internal tool, a one-off partner integration or a feature that shipped from a branch that never reached the specification. They are outside the process, so the reviews and tests that cover the documented surface do not cover them.
Both are the same failure seen from two sides. The list of what you run and the set of what answers have drifted apart, and security work is being applied to the list.
Non-production environments are part of the inventory
OWASP's guidance is explicit about this, and it is the part teams underestimate.
A staging or demo deployment usually has weaker controls, because that is what makes it convenient. When it also carries production data, or a copy of it, the weaker controls now protect real records. The guidance is that if production data must be used outside production, that deployment needs the same security controls as production, at which point the convenience has been paid for honestly.
Retiring something is a process, not a deletion
The reason zombies survive is that switching an old version off breaks a consumer you cannot enumerate, so nobody does it and the decision is deferred indefinitely.
What breaks that cycle is announcing the end date before it arrives, signalling it on the responses themselves, and watching whether anyone is still calling. The mechanics of that are the subject of the versioning guide, which covers deprecation and the Sunset header and running multiple versions at once. The security argument for doing it is this chapter, because an old version that nobody plans to switch off is an old version nobody plans to patch either.
In Routebase
api9-inventory runs two discovery probes and raises Medium findings from both.
The old-version probe reads the base URL, and where the path contains a version segment it requests every lower version down to zero. Anything that answers successfully is reported as a still-reachable old version. The shadow-endpoint probe sends OPTIONS to a small set of conventional paths, including /admin, /api/internal, /health, /metrics and /openapi.json. A path that answers with a 2xx, 401 or 403 is flagged as reachable but undocumented.
Both probes produce expected findings on a healthy API, which is why they are Medium rather than higher. A health endpoint is meant to answer, a metrics endpoint is meant to answer to your monitoring, and an old version you are patching deliberately is a decision rather than an oversight. Mark those as accepted risk with the reason, and the next scan stops arguing with you.
The other half is the retirement itself. A deprecation plan carries a sunset date, an optional successor endpoint and a migration guide. The intent to remove an endpoint then exists as a record with a date on it rather than as a conversation.

See Deprecation for the retirement workflow, Versioning for version aliases and status, and the Scanner Reference for the two probes.
Frequently asked questions
What is improper inventory management in an API?
It is the gap between the APIs you believe you run and the endpoints that actually answer. OWASP lists it as API9:2023 and its reference is CWE-1059. The risk is not that an old endpoint exists, it is that nobody is patching, monitoring or reviewing something that still returns data.
What is a zombie API?
A zombie API is a version or an endpoint that was replaced but never switched off, so it keeps serving traffic from the codebase it had on the day it was superseded. It misses every fix applied to the current version, which makes it the easiest way into a service that is otherwise maintained.
What is a shadow API?
A shadow API is an endpoint that answers without appearing in the documentation or the specification. That usually means a debug route, an internal tool or a partner integration added outside the normal process. It is not covered by whatever reviews and tests the documented surface gets, because nothing in the process knows it is there.
How do you keep an API inventory accurate?
Make the specification the record and derive from it, so a documented endpoint and a deployed endpoint are the same list by construction. Then check the other direction periodically, meaning probe for endpoints and versions that answer but are not described. The first half prevents drift and the second half catches what bypassed the process.
Last reviewed by The Routebase Team.