DEV Community

Rocky
Rocky

Posted on

The SSRF Everyone Scored as Low Because It 'Only Reaches Internal Stuff

An SSRF turns up in an internal admin panel during a cloud engagement. The app fetches a URL parameter server-side, and the tester confirms it: point it at another host on the same VNet, get the response back. Severity gets scored low. The reasoning sounds right on the surface: this thing can't reach the internet, it can only touch other internal hosts, and there's nothing juicy on the internal network to pivot to anyway. Case closed, move to the next finding.

Except "internal" on a cloud VM includes an address most people forget to think about: 169.254.169.254. That's the instance metadata service, a link-local address every major cloud provider exposes from inside a running instance, and it is very much reachable by anything that can make an internal HTTP request, including an SSRF that "only reaches internal stuff." On Azure specifically, that endpoint at /metadata/identity/oauth2/token hands back a live OAuth2 access token for whatever managed identity is attached to the VM, scoped to whatever Azure role assignments that identity holds. The one guardrail is a required Metadata: true header on the request. If the app is the one issuing the outbound call, not the tester's browser bouncing through a proxy, and the SSRF gives any way to set that header or the vulnerable code already sets it by default because that's how its own metadata calls work, the token comes back to whoever controls the SSRF, not to the app.

That token is not a low-severity finding. It's a live credential scoped to real Azure RBAC role assignments, and those assignments are very often broader than they should be, because narrowing a managed identity down to a genuinely minimal custom role is more setup work than assigning Contributor at the resource group or subscription level and moving on. A token like that can mean reading storage account keys, enumerating other resources in the subscription, or in the worse cases making changes directly through the Azure Resource Manager API, all without ever touching a username or password.

The mistake in the original triage wasn't technical, it was a scoping mistake: judging SSRF severity by what's reachable on the visible network instead of by what's reachable at all, and 169.254.169.254 doesn't show up on a network diagram. It shows up the moment someone remembers that cloud metadata services exist and checks for them specifically, every time, regardless of how "contained" the SSRF looks at first glance.

Cloud IAM attacks like this, across AWS, Azure and GCP, are exactly what the Cloud Penetration Testing Book for Beginners walks through with more than 60 hands-on labs: https://resources.codelivly.com/product/cloud-pentesting-l1/

Top comments (0)