Your API Has More Endpoints Than You Think: Finding Forgotten Swagger, OpenAPI, and Legacy Routes

Find shadow and zombie APIs by checking documentation artifacts, frontend code, subdomains, certificate history, gateways, and old versions.

Back to Blog

Your API Has More Endpoints Than You Think: Finding Forgotten Swagger, OpenAPI, and Legacy Routes

API exposure grows quietly. A team launches /api/v1, adds /api/v2, creates an internal admin host, publishes an OpenAPI document for developers, builds a mobile API, and leaves a staging gateway reachable during a migration. Years later, nobody has one complete list of what is still online.

OWASP classifies this as improper inventory management. Old API versions and forgotten hosts are valuable to attackers because they often receive fewer patches, weaker authentication, or less monitoring while still talking to real production data. The solution starts with inventory, not exploitation.

Why API inventory drifts

Modern delivery practices encourage independent deployment. Microservices, containers, serverless functions, preview environments, API gateways, and multiple mobile clients make it easy to create new endpoints. Documentation does not always retire at the same speed as infrastructure.

The result is a difference between the API the company thinks it has and the API the internet can actually reach.

Look for documentation artifacts

Swagger and OpenAPI documents are valuable development tools. They can also reveal routes, parameters, schemas, authentication methods, and deprecated operations when published unnecessarily.

/swagger
/swagger-ui/
/swagger.json
/openapi.json
/openapi.yaml
/api-docs
/docs
/redoc
/v1/openapi.json
/v2/openapi.json

Do not assume these paths are sensitive by definition. Many public APIs intentionally publish documentation. The security question is whether the documentation exposes operations that should not be public or reveals an API version the organization has forgotten.

Search frontend code and mobile configuration

Browser applications must know where their APIs live. Public JavaScript can therefore reveal hostnames, route prefixes, GraphQL endpoints, WebSocket URLs, and version strings. Mobile applications may contain similar configuration. That information is not a secret, but it is useful for asset inventory.

If production frontend code still points to legacy-api.example.com, somebody should know why.

Use DNS and subdomain discovery

APIs are often separated by hostname:

api.example.com
api-v2.example.com
mobile-api.example.com
partner.example.com
graphql.example.com
staging-api.example.com
internal-api.example.com

Vulnify's Passive Subdomain Discovery can help produce public hostname candidates. Treat those results as leads, then verify ownership, environment, and purpose.

Certificate Transparency can reveal names that DNS searches miss

Public certificate logs often contain historical service names. A certificate issued for api-old.example.com can be evidence that the host existed even if the current DNS record has been removed. Historical evidence is useful because it tells you what to search for in infrastructure inventories, cloud accounts, DNS history, and deployment configuration.

Inspect API gateways and load balancers

Public discovery should be paired with internal configuration review. API gateways, ingress controllers, reverse proxies, load balancers, WAF rules, and service meshes often contain the most accurate routing information.

Export route definitions and compare them with published documentation. Look for paths that route to old backends, wildcard rules, temporary migrations, and environment-specific exceptions.

Old API versions remain real even after the UI moves on

An endpoint can remain callable long after the official web application stopped using it. If /v1/users/{id} still reaches production data, an attacker does not care that the current frontend uses /v3/users/{id}.

Every active version needs the same minimum security controls until it is retired. That includes authentication, authorization, rate limiting, input validation, monitoring, and critical security fixes.

Compare authentication between versions

One of the highest-value checks is comparing security behavior across versions. A current endpoint may require stronger token scopes while an older route still accepts a legacy API key. Document the expected authentication mechanism for every version and test it. Do not assume a shared gateway applies identical policy if routes are configured separately.

Distinguish shadow APIs from zombie APIs

A shadow API is active but not tracked by the official inventory. A zombie API is obsolete or superseded but remains reachable. The remediation differs: shadow APIs need ownership and classification; zombie APIs usually need a retirement plan. Both can be dangerous when they process production data without current controls.

Inventory third-party data flows too

OWASP's API inventory guidance also highlights data shared with external services. An integration endpoint may no longer be needed even though the third party still receives data.

Record which service receives what data, why it is needed, who owns the integration, and what would break if it were removed. This matters during incidents because you cannot assess third-party exposure if the data flow was never documented.

Use traffic logs as a reality check

Gateway and application logs can reveal routes missing from documentation. Group requests by host, method, path template, authentication mechanism, and client. Look for low-volume endpoints that continue receiving traffic from old mobile applications, partners, cron jobs, or forgotten integrations.

Do not make raw URLs containing secrets part of a long-lived analytics dataset. Normalize paths and protect log access.

Generate documentation as part of delivery

Manual API inventories decay. Where possible, generate documentation from source definitions or gateway configuration during CI/CD. Attach owner, environment, version, network exposure, authentication method, and retirement date.

Documentation should be available to the people who need it, but sensitive internal API details do not need to be publicly indexed.

What to do when you find a forgotten endpoint

Do not immediately delete it in production. First identify clients. Check logs, mobile versions, partner integrations, scheduled jobs, and internal services. If it is unused, retire it deliberately. If it is still needed, assign an owner and bring its controls up to the current baseline.

Where immediate retirement is impossible, restrict network access or gateway exposure where practical and backport critical security controls.

Retirement needs an end state

A deprecation notice is not retirement. Define a date when the version stops accepting traffic. Communicate it to known clients, measure remaining usage, remove routing, delete obsolete DNS where applicable, and remove credentials that existed only for that version.

Keep enough historical documentation to understand old incident logs, but do not keep the application online purely because someone might still be using it.

How Vulnify fits API discovery

Vulnify's deeper scanner includes API discovery checks within its supported assessment scope. Public tools such as Exposed Paths Checker, Passive Subdomain Discovery, Technology Fingerprint, and DNS tools can help identify internet-visible clues around an API estate.

That does not replace an internal route inventory. A public scanner sees what is externally discoverable. Gateway configuration, private service discovery, source definitions, and cloud accounts complete the picture.

API inventory checklist

  • List every API hostname and environment.
  • Search for Swagger, OpenAPI, GraphiQL, and other developer consoles.
  • Compare frontend and mobile configuration with the official inventory.
  • Review API gateway, ingress, reverse-proxy, and load-balancer routes.
  • Identify every live version and its owner.
  • Compare authentication and authorization across versions.
  • Track third-party data flows.
  • Set retirement dates for obsolete versions.
  • Monitor logs before shutdown so unknown clients are found.
  • Remove DNS and routing after retirement.
  • Repeat public discovery regularly.

Build an API catalog that answers real questions

A useful inventory is more than a hostname list. For every API surface, record the environment, owner, version, authentication model, data classification, upstream and downstream dependencies, expected clients, and retirement state. If the team cannot tell whether partner-api.example.com is production or a test system, the inventory has not solved the problem.

Include a contact who can make a retirement or remediation decision. Assets without owners tend to survive because nobody feels safe changing them.

Record network exposure

Mark whether the API is internet-facing, partner-only, VPN-restricted, private-cloud-only, or internal behind a service mesh. An "internal" label is not enough if the hostname is publicly resolvable and the gateway accepts requests from the internet.

Record data sensitivity

Note whether the API processes public content, account data, payment information, credentials, personal data, internal operations, or administrator actions. This helps prioritize forgotten endpoints when several are discovered at once.

Compare documentation with live behavior

An OpenAPI file can be incomplete while the gateway exposes extra routes. The opposite also happens: the documentation still lists endpoints that were retired. Compare the specification with request logs and gateway configuration rather than deciding that any single source is authoritative.

For each mismatch, decide whether the documentation or deployment is wrong. Then fix both. Good inventory management means the description and the public surface converge.

Treat test and staging APIs as assets

Non-production APIs frequently use real production schemas, copied data, weaker authentication, verbose errors, or temporary credentials. OWASP specifically recommends avoiding production data in non-production deployments where possible and applying equivalent protection when that separation is not practical.

If a test API must be public, give it an owner, access policy, expiry date, and the same critical security fixes as production. Better still, restrict network exposure when outside access is not required.

Include WebSockets and background entry points

API inventory should not stop at REST paths. WebSocket endpoints, GraphQL subscriptions, webhook receivers, upload endpoints, RPC interfaces, and partner callback routes can be just as security-sensitive. They may live on separate hostnames or skip the gateway that protects the primary REST API.

Ask how each entry point authenticates, authorizes, limits resource use, and logs activity. Forgotten alternate protocols are a common way for the security baseline to become inconsistent.

Make discovery repeatable

Run public discovery after major infrastructure changes and on a regular schedule. The goal is not to collect endless findings. It is to detect drift between what the organization thinks is exposed and what an external observer can identify.

When a new host or route appears, classify it quickly. When a retired asset disappears, confirm the related DNS, certificates, credentials, and backend resources were cleaned up as well.

Inventory is a security control

You cannot patch, monitor, restrict, or retire an API nobody remembers. The value of API discovery is not producing a longer list of URLs. It is turning every reachable endpoint into an owned asset with an environment, version, security baseline, and retirement plan.

The best outcome is boring: when somebody asks which APIs are public, the answer comes from an inventory that matches what external discovery finds.