Hunt Shadow Api logo

Hunt Shadow Api

CommunityPopular
elementalsouls
hunt-shadow-api

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 once you have a spec or endpoint (mass assignment, JWT, OData, Swagger-chain attacks); distinct from hunt-subdomain, which owns host-level discovery. This skill owns the version-inventory and behavioral-diff workflow itself. Use when the target has versioned API paths, multiple specs, a changelog referencing deprecated endpoints, or a mobile app whose hardcoded backend calls look older than the current web app's.

Overview

Publisherelementalsouls
RepositoryClaude-BugHunter
Skill namehunt-shadow-api
Stars
4.5K
Forks
678
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by elementalsouls on GitHub. Read the source before you install it.

Installation

Install the Hunt Shadow Api AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/elementalsouls/Claude-BugHunter.git /tmp/Claude-BugHunter
mkdir -p .claude/skills
cp -r /tmp/Claude-BugHunter/skills/hunt-shadow-api .claude/skills/hunt-shadow-api
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Hunt Shadow Api in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Hunt Shadow Api on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Hunt Shadow Api is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

OWASP API9 — Improper Inventory Management (Shadow / Zombie APIs)

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.

When to use

Trigger when:

  • Versioned paths are visible (/v1/, /v2/, /api/2023-01-01/) or Accept/X-API-Version headers are in play.
  • A changelog, release notes, or deprecation notice references removed/old API behavior.
  • A mobile APK/IPA (via apk-redteam-pipeline / ios-redteam-pipeline) hardcodes endpoints that look like an older backend version than the current web app calls.
  • Multiple OpenAPI/Swagger specs are discoverable, or info.version in one spec implies others exist.

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.


Stage 1 — Enumerate the Full Version Surface

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.


Stage 2 — Pull Every Reachable Spec, Not Just the Linked One

bash
for 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:

bash
jq -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.


Stage 3 — Behavioral Diff Between Old and Current Version

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.

  • Auth strength. Does the old version accept no token, an expired token, or a lower- 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'
  • Rate limiting. Burst the same number of requests against both versions' equivalent endpoint; a missing 429 on the old version means rate-limiting was added later and never backported.
  • Input validation. Send the identical injection/oversized/malformed payload to both; the 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.).
  • Field exposure. Does the old version's response body include fields — internal IDs, other users' data, internal notes, PII — that the current version has since redacted?

Stage 4 — Deprecated / Internal Routes Never Referenced by the Current UI

  • Grep JS bundles for API calls no visible UI flow triggers (/internal/, /admin/, /debug/, /_internal/, /test/, /staging/) — reuse hunt-source-leak's JS-bundle grep patterns for this specifically.
  • Check robots.txt / sitemap.xml for disallowed API paths — a self-inflicted disclosure.
  • Mobile-app endpoint inventories (via apk-redteam-pipeline / ios-redteam-pipeline) very often 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.

False-Positive Gate

  • A version difference alone (different response shape, cosmetic field renaming) is Informational. The finding is a security-relevant regression — auth, rate-limit, or validation that got weaker going backward in version history.
  • Confirm the old endpoint is not simply an alias/proxy to the current implementation before 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.
  • A 200 on a path that just serves a static "this API version is deprecated, use v2" message is not a finding — confirm the underlying operation still executes.

Severity Table

FindingSeverity
Old version bypasses auth entirely where current version requires itCritical
Old version missing rate-limit present on current versionMedium–High (chain via hunt-brute-force)
Old version leaks extra fields (PII, internal IDs) vs. currentMedium–High
Old version accepts payloads the current version now validates/sanitizesHigh (chain to the underlying injection class)
Version is reachable but behaviorally identical to currentInformational

Related Skills & Chains

  • hunt-api-misconfig — owns exploitation once a spec or endpoint is in hand (mass assignment, 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 own host, 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 here specifically for version-diffing rather than secret extraction.
  • apk-redteam-pipeline / ios-redteam-pipeline — mobile builds routinely hardcode an older 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 once chained to actual brute-forceable impact (login, OTP, enumeration).

Frequently asked questions

What does the Hunt Shadow Api AI skill do?

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 once you have a spec or endpoint (mass assignment, JWT, OData, Swagger-chain attacks); distinct fr...

Why use Hunt Shadow Api on TypingMind?

Because you install it once and use it with any model. Hunt Shadow Api is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Hunt Shadow Api in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/elementalsouls/Claude-BugHunter/tree/main/skills/hunt-shadow-api. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Hunt Shadow Api?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Hunt Shadow Api?

As many as you like. As long as a model supports skills, you can use Hunt Shadow Api with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Hunt Shadow Api AI skill free?

Yes. It is published on GitHub by elementalsouls under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇