[← What SSRF costs you](01-what-ssrf-costs-you.md) · [Module README](../README.md) · [Allow, not block →](03-allow-not-block.md) # 2. The exploit, start to finish Run the application with no profile, so there is no `InetAddressFilter` bean at all: ```bash ./scripts/run.sh ./scripts/exploit.sh ``` The transcript is committed at [`docs/output/exploit-by-profile.txt`](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 | ... ``` 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](03-allow-not-block.md) 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 →](03-allow-not-block.md)