SSRF Through a Fetch Tool
CloudBot runs in a cloud VM with a fetch(url) tool. The cloud metadata service at 169.254.169.254 hands out the VM’s credentials. Before every fetch a guard rejects the URL if it names a loopback or link-local address as text — but the HTTP client parses the host the way browsers do.
Make fetch retrieve the VM’s credentials from /latest/meta-data/iam/security-credentials/ by writing the metadata address in a form the guard’s text filter does not recognise.
# awaiting command — type a payload and press Enter
No leads yet. Declassify intel one step at a time when you’re stuck.
How this attack works
The guard matched the URL against forbidden substrings. The HTTP client parses the host with the WHATWG rules, which accept a bare integer, hexadecimal, fewer than four dotted parts, and IPv4-mapped IPv6 as the same address. The two never agreed on what the host was, so a spelling the filter had never seen resolved straight to 169.254.169.254.
Why it's dangerous
A fetch tool that takes any URL is a server-side request forgery primitive: it reaches cloud metadata, internal admin panels, and link-local services the model was never meant to touch. One role-credentials read is often the whole blast radius. SkillTotal flags a tool that fetches arbitrary URLs as ST-MCP-DANGEROUS-TOOL.
OWASP mapping
Maps to OWASP Top 10 for LLM Applications (2025): LLM06: Excessive Agency (and OWASP Agentic Skills AST03, AST06). A string filter over URLs is the classic SSRF anti-pattern; SkillTotal’s ST-MCP-DANGEROUS-TOOL flags the over-powered fetch tool before it ships.
Related framework entries
- OWASP Agentic Skills Top 10 (2026): AST03: Over-Privileged Skills
- OWASP Agentic Skills Top 10 (2026): AST06: Weak Isolation
- MITRE ATLAS: AML.T0053 AI Agent Tool Invocation
- MITRE ATLAS: AML.T0086 Exfiltration via AI Agent Tool Invocation
These show which published techniques the level exercises. SkillTotal is not affiliated with OWASP or MITRE, and they do not endorse the labs.
How to defend
- Resolve the host to an address and check that — reject loopback, link-local (
169.254.0.0/16), and private ranges after resolution, not before. - Re-validate after every redirect; a 302 can send an allowed host to a blocked one.
- Block the metadata endpoint at the network layer (egress policy, IMDSv2, hop limit 1).
- Give the fetch tool an allowlist of hosts, not a blocklist of strings.
SkillTotal catches this class of issue deterministically (rule ST-MCP-DANGEROUS-TOOL).
FAQ
- Why isn't a string blocklist enough?
- One address has many textual spellings — decimal, hex, octal, short dotted forms, IPv4-mapped IPv6 — and the HTTP client accepts them all. A blocklist would have to enumerate every encoding; the parser accepts them by construction.
- How does SkillTotal detect this?
- ST-MCP-DANGEROUS-TOOL flags a tool whose capability is fetching an arbitrary URL — the SSRF primitive — so the over-powered tool is caught in review, before a guard has to hold the line at runtime.