A server-side request that returns the cloud instance role credentials is not a medium - it is a confirmed path to your whole account.
Most scanners rate server-side request forgery as a flat medium. The reason is structural: they prove only that the server made an outbound request, mark the checkbox, and move on. But "the server fetched a URL we chose" and "the server handed back temporary cloud credentials" are not the same finding, and rating them the same is how a real account-takeover path ends up buried in a backlog next to a missing security header.
The thing that decides severity is not the request, it is the destination. An SSRF that can reach an internal admin port is one risk. An SSRF that reaches the cloud metadata endpoint at 169.254.169.254 and reads the instance role credentials is a confirmed path to your entire account. Same vulnerability class, two different incidents.
Reachability and impact are separate facts. Reachability says the parameter will fetch a URL an attacker controls. Impact says what that fetch returned. A tool that stops at the first fact has to guess at the second, and guessing pushes everything to the safe middle - medium - because it cannot tell a blocked request to an unrouted host apart from a successful read of the IAM role.
This is the same trap as testing the render layer instead of the data layer. What the server attempts looks identical whether the boundary held or failed; a fetch to a blocked host and a fetch that drains the IAM role both start as the same outbound call. The truth is in the response body: did it carry instance-identity metadata, a file read over file://, or an internal banner that should never be reachable from the edge? That content, not the outbound attempt, is the signal, and it is the only thing we let decide how loud the finding gets to be.
So we grade SSRF along a ladder, and a finding climbs a rung only when the response earns it. Each step up is a stronger claim backed by stronger evidence, and the top rung is the only one that carries the critical rating:
The jump from likely to confirmed is the one that matters, and it is strict. We do not call it confirmed because the metadata host responded; a response can be a redirect, a timeout page, or a WAF block. It is confirmed only when the body contains the thing that proves impact - the role name and the temporary key material that the metadata service returns and nothing else does. In-band proof is what flips the bit.
Proving an SSRF must never mean running one. The boundary test our engine uses for unsafe upstream consumption sends the URL-bearing parameter a benign, non-routable marker - a host under the reserved .invalid suffix that can never resolve, so no real outbound request ever lands anywhere. The app simply tries to fetch it and fails.
The finding is confirmed in-band, with no out-of-band callback service required: the response has to echo our unique token back inside an upstream-fetch error - a resolver failure, a connection-refused, a name-not-known message from whichever stack the server runs. That pairing - our token plus a genuine fetch failure - is what proves the server forwarded an attacker-supplied URL to an HTTP client with no allow-list. It is read-only, it sends no destructive verb, and the optional OAST path stays off by default. The proof is that the boundary failed, demonstrated without crossing it.
| Rung | What the response proved | exploit_status | Severity |
|---|---|---|---|
| Reachable | The parameter forwarded our benign marker to a server-side HTTP client - it is an SSRF lever, but nothing internal was read. | reachable | medium |
| Likely | An internal-only host that should be unreachable from the edge answered the coerced request, with no sensitive content returned yet. | likely | high |
| Confirmed | The body carried instance-identity metadata, IAM role credentials, or a file read over file:// - data only the vulnerability explains. | confirmed | critical |
The ladder keeps two promises at once. It never under-rates: a confirmed metadata or file-read SSRF is critical, full stop, because temporary role credentials are a complete account compromise. And it never over-claims: a parameter that merely forwards a request is reachable, not a breach, and we say so rather than inflating it to look thorough.
A confirmed cloud-metadata SSRF lands with the PoC request that triggered it and the leaked response attached as evidence, credentials masked so the report itself is not a second exposure. The engineer opens the finding and sees the role name and the shape of the key material the endpoint returned - proof, not a category label that says "SSRF, medium, investigate."
That difference changes the clock. A confirmed critical carries the tightest SLA we set, because an attacker holding instance role credentials can pivot from one vulnerable parameter to your storage, your databases, and your other services in the same account, often within the lifetime of a single temporary token. Rating it medium does not make it less urgent - it just guarantees it gets worked late, after the header warnings and the verbose-error notes that happened to share its severity band.
Separating reachable from likely from confirmed is not bureaucratic bookkeeping. It is what lets a team trust the top of the queue: every critical on the list is a leak someone can reproduce from the attached request, and every reachable is an honest gap rather than a guess dressed up as a breach. Severity you can defend line by line is the only kind that survives an enterprise audit.