# SSRF to cloud metadata credentials

Server-side fetch or tunnel reaching 169.254.169.254 or internal metadata, leaking cloud credentials or tokens

_Area: Cloud and container security. Seen in 3 disclosed reports; 3 confirmed bounties, median $1,337, range $1,337-$25,000; latest 2022-04-23. Updated 2026-10-23._

## How it works
A server fetches a URL or target the user can influence. The code assumes the destination is public, but the network path also reaches the cloud link-local metadata address (169.254.169.254) and internal ranges. The metadata service answers unauthenticated requests from the instance, returning cloud credentials or tokens. The broken assumption is "user-supplied target means external target"; nothing enforces that the resolved destination is outside the instance's own network. The same reachability can come from a fetch primitive or from a tunnel that bypasses a blocked login shell.

## Where it shows up
- Any server-side fetch primitive (URL, host, or address field) whose destination is not validated after resolution
- Screenshot or headless-browser services that render attacker-supplied URLs [E1](https://bugbountylibrary.com/r/h1%3A341876.md)
- Sandboxes that execute attacker-supplied install scripts without egress filtering to the metadata endpoint [E2](https://bugbountylibrary.com/r/blog%3Acodemuch-tech-2022-04-23-supply-chain-counterattack.md)
- Managed nodes where SSH tunneling reaches metadata the platform assumes is unreachable [E3](https://bugbountylibrary.com/r/blog%3Alf-lc-vrp-181521559c.md)
- Legacy metadata paths that skip the usual header requirement, and metadata concealment left disabled [E1](https://bugbountylibrary.com/r/h1%3A341876.md)

## How to review
Check the exact invariant: every server-side fetch resolves to a public address, and the metadata IP plus private ranges are blocked at connect time, not just by string matching. Verify:
- Destination is validated after DNS resolution and on every redirect hop
- Workloads cannot reach IMDS; egress filtering is present, not assumed [E2](https://bugbountylibrary.com/r/blog%3Acodemuch-tech-2022-04-23-supply-chain-counterattack.md)
- Metadata concealment is enabled so bootstrap material is not exposed [E1](https://bugbountylibrary.com/r/h1%3A341876.md)
- SSH port forwarding on managed nodes cannot reach the metadata service, even with nologin shells [E3](https://bugbountylibrary.com/r/blog%3Alf-lc-vrp-181521559c.md)

## Variants seen
- Screenshot service SSRF to GCP metadata, leaking kube-env kubelet credentials [E1](https://bugbountylibrary.com/r/h1%3A341876.md)
- Analysis sandbox reaching GCP metadata for an OAuth token [E2](https://bugbountylibrary.com/r/blog%3Acodemuch-tech-2022-04-23-supply-chain-counterattack.md)
- SSH tunnel from a nologin shell to node metadata, stealing kubelet credentials [E3](https://bugbountylibrary.com/r/blog%3Alf-lc-vrp-181521559c.md)

## Impact and severity
Led to cloud credential and token theft [E1](https://bugbountylibrary.com/r/h1%3A341876.md)[E2](https://bugbountylibrary.com/r/blog%3Acodemuch-tech-2022-04-23-supply-chain-counterattack.md), and escalated toward cluster-admin in the GKE case [E3](https://bugbountylibrary.com/r/blog%3Alf-lc-vrp-181521559c.md). Severity is high because metadata credentials often carry broad scope; it worsens when tokens are long-lived, concealment is off [E1](https://bugbountylibrary.com/r/h1%3A341876.md), or the identity can reach cluster bootstrap material [E3](https://bugbountylibrary.com/r/blog%3Alf-lc-vrp-181521559c.md).

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A341876.md
- E2: https://bugbountylibrary.com/r/blog%3Acodemuch-tech-2022-04-23-supply-chain-counterattack.md
- E3: https://bugbountylibrary.com/r/blog%3Alf-lc-vrp-181521559c.md
