Detecting shadow and zombie APIs by analyzing OpenAPI drift with DAST

Detecting shadow and zombie APIs by analyzing OpenAPI drift with DAST

As release cycles accelerate, a quiet gap opens between what API documentation declares and what actually responds in staging or production. Undocumented routes (shadow APIs) and abandoned legacy versions (zombie APIs) are serious exposures because they often lack modern authentication, rate limiting, and monitoring. By comparing what a DAST scan finds at runtime against the OpenAPI contract, engineering teams can pinpoint schema drift and close hidden entry points before attackers find them.

Why OpenAPI specifications alone leave blind spots

Many engineering organizations anchor their API security workflows to a central OpenAPI or Swagger specification. The working assumption is simple: if the spec is maintained alongside the code, a spec-driven scanner will exercise the complete attack surface. In live environments, that assumption regularly breaks down.

Schema drift happens naturally through everyday development pressure:

  • Expedited hotfixes. Developers add temporary debugging or migration routes to staging or production without registering them in the API definition.
  • Deprecated routing residue. Legacy paths like /v1/users keep responding in the background even though the documentation only describes /v2/users.
  • Gateway routing misconfigurations. Internal endpoints slip through reverse proxies and ingress controllers without ever appearing in a published specification.

If testing relies only on routes declared in the contract, teams systematically skip the least protected doors. This is where dynamic application security testing earns its place: it evaluates the running application from the outside, matching what an external attacker can actually reach.

Distinguishing shadow endpoints from zombie APIs

For actionable triage, teams need to separate new, uncataloged functionality from forgotten legacy endpoints. Both are schema drift, but they emerge from different phases of the software lifecycle and need different remediation. OWASP groups both under API9:2023 Improper Inventory Management in the API Security Top 10.

The table below compares the two categories with properly documented endpoints:

Endpoint typeCharacteristicsPrimary security riskDetection methodRemediation
Documented APIDeclared in the OpenAPI spec with current parameter types and auth schemesBusiness logic flaws, auth misconfiguration, standard injection vectorsSpec-driven DAST scans and contract tests in CI/CDContinuous scanning and routine patching
Shadow APILive route absent from the current spec; often new, internal, or ad hocOften bypasses centralized authentication, rate limiting, and WAF inspectionCrawling, heuristic path discovery, and reconciling traffic logs against the specDocument it in the spec or remove the route
Zombie APIDeprecated route (e.g. /v1) dropped from the spec but still served by the backendUnpatched code, outdated business logic, bypass of newly hardened access controlsVersion-path permutations, diffing against historical specs, dynamic crawlingRemove legacy handlers and strip the routing rules from the proxy

Because monitoring and audit tooling usually assumes the specification is complete, both kinds of orphaned path tend to run without meaningful observability until an incident brings them to light.

Zombie endpoints are especially prone to OWASP Top 10 issues such as broken object-level authorization and authentication bypass. When developers fix a vulnerability in /v2, they often forget that an exposed /v1 route still runs the old queries against the same data store.

Detecting schema drift between specs and live endpoints

Uncovering drift means combining deterministic contract checks with exploratory dynamic testing. Spec-only scans are blind to unlisted paths, while pure black-box crawling struggles to build valid payloads for complex, nested JSON endpoints.

An effective detection workflow has four phases:

  1. Start from the spec in source control. Use the OpenAPI definition from the same commit that is being deployed, rather than a hosted copy that may lag behind the code.
  2. Run heuristic runtime discovery. Pair standard spidering with structural probing such as version-path toggling, common administrative paths, and response fingerprinting. An AI agentic scan can reason over returned payloads to find deeply buried endpoints that nothing links to.
  3. Compute path-level drift. Cross-reference every responding route against the paths in the spec. First record how the application answers a path that certainly does not exist—many frameworks and SPAs return 200 for everything—then flag any undocumented route whose 200, 401, or 403 response differs from that baseline.
  4. Inspect parameter-level drift. Check whether live endpoints accept query or body parameters that the spec does not declare, such as debug=true or is_admin=1. This catches mass-assignment vectors hiding inside otherwise documented endpoints.

Running this verification continuously with DAST in CI/CD pipelines catches unplanned surface expansion before code reaches production.

Interpreting results without false confidence

Comparing an OpenAPI contract with a live environment takes disciplined interpretation. A 404 during black-box scanning does not prove a route is gone: it may only respond to a specific HTTP method or valid path parameters, and some APIs deliberately return 404 instead of 401 or 403 to hide resources from unauthenticated callers.

Watch for these failure modes during triage:

  • A WAF masking origin weaknesses. If an edge firewall returns 403 to scanner probes, it is tempting to assume the route is locked down. That only proves the edge blocked the request—not that the origin service enforces access control if the edge is bypassed.
  • Dismissing 401 responses as noise. An unlisted endpoint that answers 401 Unauthorized is confirmed to be live. If it is missing from the OpenAPI document, it is a shadow API that belongs in your inventory.
  • Confusing governance drift with exploitable flaws. An undocumented parameter is an inventory defect, but it becomes a serious vulnerability if the backend silently binds it to state changes (mass assignment).

For trustworthy data, run authenticated scans against staging or preview environments where the scanner can reach handlers without edge filters masking origin behavior.

Building a continuous API inventory workflow

Eliminating shadow and zombie endpoints cannot be a one-off audit. As services evolve through rapid release cycles, drift comes back unless platform teams build guardrails into their delivery pipelines.

A resilient API inventory process rests on three rules:

  • Enforce spec parity at pull request. Require any pull request that changes routes, query parameters, or payload bodies to update the OpenAPI document in the same change.
  • Automate drift checks in staging. Schedule recurring dynamic scans that compare reachable paths with the specification, and fail builds or raise alerts when uncataloged endpoints respond.
  • Decommission legacy endpoints decisively. When moving from v1 to v2, set a firm deprecation window and then remove the old code at the service level, rather than just dropping the paths from the developer portal.

Scryn lets teams combine OpenAPI-driven scans with AI agentic discovery, so the routes a scan actually reaches can be checked against what the spec documents—visit scryn.cloud to learn more.