The Hacker now resolves the address to its canonical form and blocks every private range: 127, 10, 192.168, and 172.16 through 31. But he forgot the link-local address 169.254.169.254, the cloud metadata service that hands out the server’s access keys.
The same preview tool; the filter now really blocks private ranges (127, 10, 192.168, 172.16-31) but forgot the link-local range 169.254, which is the cloud metadata service address 169.254.169.254.
Steal the Ravens’ cloud access keys from the metadata service, through the server.
You stole the cloud access keys from the metadata service via SSRF.
Why the solution worked
Even a private-range filter, after correct resolution, misses the cloud metadata address 169.254.169.254 — the most dangerous SSRF target, because it hands out the server role’s keys, so whoever reaches it controls the cloud resources. The fix: allowlist destinations rather than blacklist, block the metadata service at the network level (IMDSv2 requires a token), and give the server the least privilege possible so that even leaked keys do limited harm.
The root cause
The blocklist was not exhaustive and missed the link-local range 169.254 that hosts the cloud metadata service; blocklists always forget some case.
How the code is fixed
A blacklist always forgets one address; an allowlist permits only the known-safe set. Block the metadata service at the network level too.
Vulnerable code
function isPrivate(ip) {
// Blocks private ranges but forgets link-local 169.254.0.0/16 (cloud metadata).
return /^127\.|^10\.|^192\.168\.|^172\.(1[6-9]|2\d|3[01])\./.test(ip);
}
Safe code
const ALLOW = new Set(['https://images.cdn.example']);
async function allowed(url) {
if (!ALLOW.has(new URL(url).origin)) return false; // allowlist, not blacklist
const { address } = await dns.lookup(new URL(url).hostname);
return !isPrivate(address) && !isLinkLocal(address); // 169.254/16 included
}
// Plus: require IMDSv2, and give the instance a least-privilege role.
Impact in the real world
Reaching the cloud metadata service leaks the server role temporary credentials and has been used in massive breaches of millions of records.
How defenders detect it
Defenders use an allowlist not a blocklist, block the metadata service at the network layer, enforce IMDSv2, and alert on requests toward 169.254.