1
0
Files
spring-security-demo/ssrf/docs/02-the-exploit.md
2026-08-29 09:31:09 +05:30

2.2 KiB

← What SSRF costs you · Module README · Allow, not block →

2. The exploit, start to finish

Run the application with no profile, so there is no InetAddressFilter bean at all:

./scripts/run.sh
./scripts/exploit.sh

The transcript is committed at docs/output/exploit-by-profile.txt. The first block is this one:

http://127.0.0.1:8080/internal/credentials    FETCHED | {"SecretAccessKey":"wJalrXUtnFEMI-...
http://localhost:8080/internal/credentials    FETCHED | {"SecretAccessKey":"wJalrXUtnFEMI-...
http://[::1]:8080/internal/credentials        FETCHED | {"SecretAccessKey":"wJalrXUtnFEMI-...
http://172.16.10.3:8080/internal/credentials  FETCHED | {"SecretAccessKey":"wJalrXUtnFEMI-...
http://example.com/                           FETCHED | <!doctype html>...

Four targets, four sets of credentials, and the legitimate outbound call still works. That last row matters as much as the others: any mitigation has to leave it intact, and one of the configurations in chapter 3 does not.

Why four targets and not one

127.0.0.1 is the one every tutorial blocks. The others are why a hand-written check usually leaks:

Target What it defeats
localhost checks written against the literal string 127.0.0.1
[::1] checks that only ever consider IPv4
172.16.10.3 checks that stop at loopback and forget RFC 1918

The fourth is this container's own address on its network interface. It is the same process, reached the same way, over a route that a loopback-only rule does not cover. In a real deployment it is the pod next door.

Blocking by string is hopeless in a way that is easy to underestimate. 0x7f.0.0.1, 2130706433, 127.1, a DNS name you control that resolves to 127.0.0.1, and a redirect from a public URL to a private one all reach loopback without the string 127.0.0.1 appearing anywhere in the request. This is why the check belongs at address-resolution time and not in a validator over the URL — which is exactly what InetAddressFilter is.

Allow, not block →