Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Hunt shadow / zombie / undocumented API surface (OWASP API9 Improper Inventory Management) — enumerate the full API version history (v1/v2/beta/legacy paths, header- and subdomain-based versioning), pull and diff every reachable OpenAPI/Swagger spec (including ones only findable via the Wayback Machine), and behaviorally diff old vs. current versions for auth/rate-limit/validation regressions rather than just response-shape differences. Distinct from hunt-api-misconfig, which owns exploitation o
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-14 | ✗→✓ | ▲ Improved | 61% | 0% |
| case-17 | ✗→✓ | ▲ Improved | 31% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 100% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 24% | 0% |
| case-07 | ✓→✓ | = Same ✓ | 33% | 0% |
As an API evolves, old versions and internal/staging routes routinely stay reachable without receiving the same security fixes as the current version — because nobody tracks that they still exist. The bug is rarely in one endpoint; it's in the delta between what an old version enforces and what the current version enforces on the same operation.
Trigger when:
/v1/, /v2/, /api/2023-01-01/) or Accept/X-API-Versionheaders are in play.
apk-redteam-pipeline / ios-redteam-pipeline) hardcodes endpointsthat look like an older backend version than the current web app calls.
info.version in one spec implies othersexist.
DO NOT use for single-version APIs with no version history — there's nothing to diff; go straight to hunt-api-misconfig for direct exploitation of the one surface that exists.
bash# Path-based versioning for v in v1 v2 v3 v4 beta alpha internal legacy old 2022-01-01 2023-01-01 2024-01-01; do curl -s -o /dev/null -w "%{http_code} /api/$v/\n" "https://$TARGET/api/$v/" done # Header-based versioning curl -s -H "X-API-Version: 1" https://$TARGET/api/users curl -s -H "Accept: application/vnd.company.v1+json" https://$TARGET/api/users # Subdomain-based versioning for sub in api api-v1 api-v2 apiv1 apiv2 legacy-api old-api internal-api staging-api; do curl -s -o /dev/null -w "%{http_code} $sub\n" "https://$sub.$TARGET/" done
A 200/401/403 on an old version path (anything but 404/connection-refused) means the version is still live and worth carrying into Stage 3, even if it demands auth.
bashfor path in openapi.json swagger.json v1/swagger.json v2/swagger.json v3/api-docs \ api-docs.json swagger/v1/swagger.json .well-known/openapi.json; do curl -s -o /dev/null -w "%{http_code} /$path\n" "https://$TARGET/$path" done # Wayback Machine — a DEPRECATED version's spec often stays indexed after the live link is removed curl -s "http://web.archive.org/cdx/search/cdx?url=$TARGET/*swagger*&output=json&collapse=urlkey" curl -s "http://web.archive.org/cdx/search/cdx?url=$TARGET/*openapi*&output=json&collapse=urlkey"
When more than one spec resolves (a current one and an archived/old one), diff the endpoint inventories directly:
bashjq -r '.paths | keys[]' v1-swagger.json | sort > /tmp/v1_paths.txt jq -r '.paths | keys[]' v2-swagger.json | sort > /tmp/v2_paths.txt comm -23 /tmp/v1_paths.txt /tmp/v2_paths.txt # in v1 only — candidates for "still live but forgotten"
For every path in that diff, confirm it's still reachable against the v1 base URL. A route documented only in the old spec that still returns something other than 404 is a zombie- endpoint candidate — carry it into Stage 3.
For each operation that exists in both versions, compare security-relevant behavior, not response shape. Response shape differences are Informational; behavioral security regressions are the finding.
privilege token that the current version rejects? bash curl -s -H "Authorization: Bearer $EXPIRED_TOKEN" https://$TARGET/api/v1/users/me -w '\n%{http_code}\n' curl -s -H "Authorization: Bearer $EXPIRED_TOKEN" https://$TARGET/api/v2/users/me -w '\n%{http_code}\n'
endpoint; a missing 429 on the old version means rate-limiting was added later and never backported.
old version accepting what the new one rejects means hardening happened forward-only — chain into whichever injection class the payload targets (hunt-sqli, hunt-idor, etc.).
users' data, internal notes, PII — that the current version has since redacted?
/internal/, /admin/, /debug/,/_internal/, /test/, /staging/) — reuse hunt-source-leak's JS-bundle grep patterns for this specifically.
robots.txt / sitemap.xml for disallowed API paths — a self-inflicted disclosure.apk-redteam-pipeline / ios-redteam-pipeline) veryoften reference an older backend version than the current web app calls. Treat every APK/IPA-sourced endpoint as a version-diff candidate against the live web API.
Informational. The finding is a security-relevant regression — auth, rate-limit, or validation that got weaker going backward in version history.
claiming a behavioral difference — send a payload that would actually behave differently under old vs. new logic, not just compare a version string in the response body.
200 on a path that just serves a static "this API version is deprecated, use v2" messageis not a finding — confirm the underlying operation still executes.
| Finding | Severity | |---|---| | Old version bypasses auth entirely where current version requires it | Critical | | Old version missing rate-limit present on current version | Medium–High (chain via hunt-brute-force) | | Old version leaks extra fields (PII, internal IDs) vs. current | Medium–High | | Old version accepts payloads the current version now validates/sanitizes | High (chain to the underlying injection class) | | Version is reachable but behaviorally identical to current | Informational |
hunt-api-misconfig — owns exploitation once a spec or endpoint is in hand (massassignment, JWT attacks, OData, Swagger-chain attacks). This skill hands it a sharper target: "here's a zombie endpoint with weaker validation than the current one."
hunt-subdomain — owns host/subdomain-level discovery (api-v1.target.com as its ownhost, potential takeover). This skill owns what happens once you're inside a given host's version surface.
hunt-source-leak — JS-bundle grep for internal/undocumented calls; reused herespecifically for version-diffing rather than secret extraction.
apk-redteam-pipeline / ios-redteam-pipeline — mobile builds routinely hardcode anolder API version; every mobile-sourced endpoint is a version-diff candidate.
hunt-brute-force — a rate-limit regression found here is only a complete finding oncechained to actual brute-forceable impact (login, OTP, enumeration).
Other measured skills in the registry, with their headline benchmark lift.