← marwandiallo.comlabs

SSRF URL analyzer

Paste a URL the agent or backend is about to fetch. The analyzer decodes the host (decimal, hex, octal, alias), checks against cloud metadata IPs, RFC 1918, link-local, loopback, and unusual URL schemes, and surfaces eight SSRF-relevant findings.

Runs the canonical 4-stage hardening flow on the server: parse → pre-flight rule check → DNS resolve + re-check every IP (DNS-rebinding defence) → bounded fetch. Each stage's pass/fail is shown below.

Resolved: http://169.254.169.254/latest/meta-data/iam/security-credentials/
cloud metadatalink-local
2 findings2 critical,
CRITICALSSRF01

Cloud instance metadata endpoint

169.254.169.254 (AWS, GCP, Azure) and 100.100.100.200 (Alibaba) are the SSRF target. Reading IAM credentials, service account tokens, and user-data from these endpoints has been the root cause of Capital One, multiple GCP misconfigurations, and many bug-bounty payouts. On AWS, only IMDSv2 (with required token) blocks naive SSRF. On all three, host-level firewalling of link-local from application processes is the durable fix.

169.254.169.254

standards: OWASP Top 10 A10 (SSRF) · CWE-918 · AWS IMDSv2 guidance · Capital One 2019 (post-mortem)

CRITICALSSRF08

Cloud metadata path pattern

Path matches a known cloud metadata URL (AWS /latest/meta-data, GCP /computeMetadata/v1, Azure /metadata/instance). Even if the host validator passed, the path strongly suggests an exfiltration attempt.

/latest/meta-data/iam/security-credentials/

standards: OWASP Top 10 A10 · CWE-918 · MSRC IMDS guidance

Fetcher sandbox — naive vs hardened

Pick one of 10 catalog payloads. Two fetchers receive the same request: a naive one (substring blocklist on the raw URL) and a hardened one (scheme allowlist → CRLF check → header strip → host canonicalisation → IP blocklist → IP-pinned fetch). The deterministic transcripts show what each would put on the wire and which hardened rule blocks the call. Reproduce any scenario over the wire with POST /api/ssrf-fetch { "scenarioId": "...", "mode": "..." }.

Decimal-encoded IPv4 → AWS IMDS · Capital One breach (2019) — SSRF to AWS IMDS, ~106M records (FinCEN report)

169.254.169.254 expressed as the decimal 32-bit integer 2852039166. URL parsers in many languages happily resolve this; string-match validators that look for '169.254' miss it.

GET http://2852039166/latest/meta-data/iam/security-credentials/

Naive fetcher

  1. Receive URL
    http://2852039166/latest/meta-data/iam/security-credentials/
  2. Naive validation
    Substring check for '169.254' / 'metadata' on the raw URL. Encoded hosts and header smuggles slip through.
  3. DNS lookup
    2852039166 → 169.254.169.254
  4. Wire send
    GET http://169.254.169.254/latest/meta-data/iam/security-credentials/
  5. Response received
    200 OK Content-Type: text/plain ec2-instance-role {"Code":"Success","AccessKeyId":"ASIA…","SecretAccessKey":"…","Token":"…"}
  6. LEAK
    AWS temporary credentials (AccessKeyId/SecretKey/Token)
  7. naive fetcher finished
    attacker now holds the leaked secret

Hardened fetcher

  1. Receive URL
    http://2852039166/latest/meta-data/iam/security-credentials/
  2. Scheme allowlist
    {http, https} only.
  3. Canonicalise host
    Decode decimal/hex/octal hostnames to dotted-quad before any check.
  4. Strip caller headers
    Drop Host, Metadata-Flavor, X-aws-ec2-metadata-token from caller-supplied headers.
  5. DNS lookup once + IP blocklist
    Block 169.254/16, 127/8, ::1, fe80::/10, fc00::/7, RFC1918.
  6. Pin validated IP for fetch
    Dial the validated IP; never re-resolve the hostname.
  7. BLOCK [H-IPRANGE]
    169.254.169.254 is cloud metadata
  8. hardened fetcher finished
    request refused before any DNS lookup or socket open; no data left the application

What this proves