SSRF: The Complete Practical Guide to Server-Side Request Forgery
Reaching Internal Services with SSRF
Reach internal-only services with SSRF: loopback vs link-local vs private ranges, port scanning by timing, and unauthenticated internal admin panels.
Published
The reason SSRF is so powerful is position. The server lives behind the firewall, so from its point of view the internal network is wide open: loopback, private ranges, and internal hostnames that you could never touch from outside. Reaching those services is where an SSRF stops being a curiosity and starts being an incident.
The server's privileged network view
A firewall separates "outside" from "inside," and the server is inside. Requests you send from the internet get blocked at the perimeter, while requests the server makes start past it. So an SSRF inherits reach to:
- The host itself on loopback.
- Other machines on the internal network.
- Services that bind to private addresses and assume no external exposure.
You are not breaking through the firewall. You are asking a machine that is already inside to fetch things for you.
Loopback, link-local, and private ranges
Know the address ranges worth aiming at, because each means something:
127.0.0.0/8 loopback the server talking to itself
::1 loopback IPv6 form
169.254.0.0/16 link-local includes the cloud metadata IP 169.254.169.254
10.0.0.0/8 private internal hosts
172.16.0.0/12 private internal hosts
192.168.0.0/16 private internal hostsLoopback reaches on-box services, link-local reaches the metadata endpoint, and the private ranges reach the rest of the internal network.
Port scanning through SSRF
You can turn one SSRF into an internal port scanner by reading response differences. Request a host and port and watch what comes back:
http://127.0.0.1:22/ SSH
http://127.0.0.1:3306/ MySQL
http://127.0.0.1:6379/ Redis
http://10.0.0.5:8080/ an internal web app- Open: fast connect, often a banner or a protocol-mismatch error (the service answered, just not in HTTP).
- Closed: fast connection-refused.
- Filtered: hangs until the timeout.
Sweep ports and hosts, and the timing map tells you what is alive, even blind.
Internal hostname and service discovery
Internal networks use friendly names. In containerized and cloud setups, services are reachable by short names:
http://redis:6379/
http://elasticsearch:9200/_cat/indices
http://postgres:5432/
http://metadata/ (some environments alias the metadata host)Try common service names, the names you see leaked in error messages or config, and the metadata hostnames for the cloud you are on.
Non-HTTP ports and what breaks
Not every internal service speaks HTTP, and a plain HTTP fetcher will often choke on them. A request to a Redis or MySQL port sends HTTP bytes the service does not understand, so you get an error rather than clean output. That error still confirms the port is open, and with protocol smuggling you can do far more than confirm it (see SSRF to RCE and compromise for gopher:// and friends).
Hitting unauthenticated internal admin panels
The highest-value internal targets are the ones left unauthenticated because "only internal traffic reaches them":
- Framework internals (a Spring Boot
actuator, a debug console). - Search and data stores (Elasticsearch, a database admin UI).
- Orchestration and metrics dashboards.
- The cloud metadata service, which is the subject of its own spoke.
Each of these trusts the internal network, and SSRF makes you part of it. When a filter stands between you and these targets, move to allow-list and filter bypass. Practice reaching internal services on a free live target.
← Back to SSRF: The Complete Practical Guide to Server-Side Request Forgery