Skip to main content
SkillTotal
cd ~/labs
visitor@skilltotal:~$ cat ./labs/ssrf-fetch-tool/mission.txt

SSRF Through a Fetch Tool

lab 17 · ST-MCP-DANGEROUS-TOOL · LLM06
mission.txt
scenario

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.

objective

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.

session — ssrf-fetch-tool

# awaiting command — type a payload and press Enter

Not sure where to start?
▚ Intel

No leads yet. Declassify intel one step at a time when you’re stuck.

▰ Dossierclassified — solve to unseal

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

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).

Scan AI component (free)

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.