47 lines
2.2 KiB
Markdown
47 lines
2.2 KiB
Markdown
[Module README](../README.md) · [The exploit →](02-the-exploit.md)
|
|
|
|
# 1. What SSRF actually costs you
|
|
|
|
Server-Side Request Forgery is not a parsing bug. Every line of
|
|
[`LinkPreviewController`](../src/main/java/com/ankurm/ssrf/LinkPreviewController.java) is
|
|
correct in isolation. The vulnerability is architectural: a process that will fetch a URL of the
|
|
caller's choosing sits inside a network where some destinations are privileged, and privilege in
|
|
that network is decided by source address.
|
|
|
|
That is why SSRF is so consistently severe. The attacker does not need to reach your internal
|
|
service — they need your service to reach it, and it already can.
|
|
|
|
The canonical prize is the cloud instance metadata service on `169.254.169.254`, which hands
|
|
short-lived role credentials to anything on the instance that asks, with no authentication. But
|
|
the ordinary case is duller and more common: an internal admin API, an unauthenticated actuator,
|
|
a `/metrics` endpoint, an Elasticsearch cluster, a Redis instance, a sidecar's admin port.
|
|
|
|
## The features that are this bug
|
|
|
|
If your service does any of these with a user-supplied URL, you have this shape:
|
|
|
|
- link previews and URL unfurling
|
|
- webhook registration and its "send a test event" button
|
|
- avatar or document "import from URL"
|
|
- server-side PDF and screenshot rendering
|
|
- XML parsing with external entities enabled
|
|
- anything that follows a redirect it did not choose
|
|
|
|
## What Boot 4.1 changed
|
|
|
|
Before 4.1 you wrote the defence yourself: resolve the host, check the address against your own
|
|
list of forbidden ranges, and hope you did it in the same lookup the connection would later use.
|
|
That last part is where hand-rolled checks fail — see
|
|
[chapter 4](04-where-the-filter-runs.md).
|
|
|
|
Boot 4.1 added
|
|
[`InetAddressFilter`](https://docs.spring.io/spring-boot/4.1/api/java/org/springframework/boot/http/client/InetAddressFilter.html),
|
|
declared once as a bean and applied by `HttpClientAutoConfiguration` to every auto-configured
|
|
HTTP client. The check moves down into the client's own name resolution, which is the only place
|
|
it can be both mandatory and correctly timed.
|
|
|
|
It is a real improvement and it is easy to configure backwards. The next three chapters are
|
|
about that.
|
|
|
|
[The exploit →](02-the-exploit.md)
|