July 25, 2026
Server-Side Request Forgery (SSRF): A Complete Technical Guide
A complete guide for developers and penetration testers — what SSRF is, why it happens, how attackers exploit it (basic and blind), and how…
By Umair Majeed
7 min read
A complete guide for developers and penetration testers — what SSRF is, why it happens, how attackers exploit it (basic and blind), and how to prevent it.
1. What Is SSRF?
Server-Side Request Forgery (SSRF) is a web application vulnerability that allows an attacker to induce the server to make an HTTP — or other protocol — request to a destination of the attacker's choosing, rather than the destination the developer intended.
In plain terms: an application feature fetches a URL on the server's behalf. Instead of supplying a normal, expected URL, the attacker supplies one that points somewhere sensitive — an internal service, localhost, or a cloud metadata endpoint. The server makes that request, using its own network position and its own identity.
The defining characteristic of SSRF is that the attacker's browser never talks to the internal target directly. The vulnerable application is the proxy.
2. Why SSRF Happens
SSRF exists because developers build features that must fetch a remote resource based on user input, and the input is trusted more than it should be.
Root causes:
- No validation of the URL or host supplied by the user.
- Only the scheme is checked (
http://vshttps://), never the actual hostname or IP. - Blacklisting known-bad hosts (
127.0.0.1,localhost) instead of whitelisting known-good ones — blacklists are trivially bypassed. - Implicit trust in "internal" services, on the assumption that no external user can reach them — forgetting that the vulnerable app itself can be abused as a pivot.
- DNS resolution happening at request time rather than at validation time, enabling DNS rebinding.
- Server-side HTTP clients that follow redirects automatically without re-validating the new destination.
A vulnerable code example (C#):
csharp
string url = Request.Form["url"];
var client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(url);
return await response.Content.ReadAsStringAsync();string url = Request.Form["url"];
var client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(url);
return await response.Content.ReadAsStringAsync();Because url is never checked against an allowlist, never restricted to http/https, and never re-resolved against private IP ranges, an attacker can point it at any destination the server can reach — including itself, its internal network, or the cloud metadata service.
3. Client-Side Request vs. Server-Side Request
Client-Side Request
- Sent by the user's browser
- Operates from the public internet, outside the firewall
- Can only reach what the user's own machine can reach
- Limited by the user's own network — can't bypass firewalls
- Attacker has full control and sees the response directly
Server-Side Request (SSRF)
- Sent by the web application's backend
- Often operates inside the internal network / VPC
- Can reach internal admin panels, databases, cloud metadata, and other microservices
- Can bypass external firewalls entirely, since the request originates from a trusted internal source
- Attacker's visibility depends on the case — sometimes visible ("basic" SSRF), sometimes invisible ("blind" SSRF)
Example contrast:
- Client-side: a user types a URL into their browser, and the browser fetches it directly.
- Server-side (SSRF): a "fetch avatar from URL" feature accepts a URL, and the server itself goes and fetches it. Pointing that URL at
http://169.254.169.254/latest/meta-data/means the server — not the attacker — requests cloud metadata, and may hand the result back.
GET /fetch-image?url=https://example.com/image.png
POST /webhook?callback=https://callback.example.com
POST /api/import?source=http://external.com/data.json
GET /preview?link=https://example.com/articleGET /fetch-image?url=https://example.com/image.png
POST /webhook?callback=https://callback.example.com
POST /api/import?source=http://external.com/data.json
GET /preview?link=https://example.com/article5. Common SSRF Entry Points
Look for parameters that smell like they trigger a server-side fetch — in URL query strings, JSON request bodies, and even headers or uploaded files:
6. Basic (Non-Blind) SSRF
In basic SSRF, the response from the internal request is reflected back to the attacker — either directly, or leaked through an error message, a preview thumbnail, or debug output.
How it unfolds:
- The attacker sends a request containing a malicious URL in place of the expected one.
- The server makes the request to that target on the attacker's behalf.
- The server returns some form of the response content back to the attacker.
A Normal (Non-Vulnerable) Application
A properly built "import avatar from URL" feature restricts the destination to an allowlist of trusted image CDNs, rejects private IP ranges after resolving the hostname, and never returns raw fetch output to the client:
POST /profile/avatar
{ "url": "https://cdn.trusted-images.com/pic.jpg" }
→ 200 OK — image stored, only a thumbnail URL is returned to the clientPOST /profile/avatar
{ "url": "https://cdn.trusted-images.com/pic.jpg" }
→ 200 OK — image stored, only a thumbnail URL is returned to the clientThe Same Feature, Vulnerable
The vulnerable version performs no destination validation at all, and — critically — echoes fetch errors or content back to the caller:
POST /profile/avatar
{ "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/" }
→ 200 OK
{ "preview": "role-name\nAKIA...\n<secret access key>..." }POST /profile/avatar
{ "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/" }
→ 200 OK
{ "preview": "role-name\nAKIA...\n<secret access key>..." }Other common basic-SSRF targets:
7. Blind SSRF
In blind SSRF, the server makes the request, but the attacker never sees the response body. The vulnerability is confirmed only through indirect signals.
Detection techniques:
- Timing — a request to a valid internal host takes measurably longer or shorter than a request to a non-existent one, confirming a network call happened.
- Out-of-band (OOB) interaction — point the server at an attacker-controlled domain and watch for a DNS lookup or HTTP hit on an external listener.
- Error message differences — "connection refused" vs. "timeout" vs. a generic
200 OKcan reveal whether an internal port or service exists, without ever exposing its content.
Blind SSRF is still dangerous: it can be chained into internal port scanning, into triggering state-changing actions on internal endpoints (an admin action, a cache flush), or escalated to full SSRF through a secondary bug.
GET /fetch?url=http://<attacker-domain>/xxxxx
(no response content is returned to the attacker —
confirmation comes from the attacker's own DNS/HTTP logs)GET /fetch?url=http://<attacker-domain>/xxxxx
(no response content is returned to the attacker —
confirmation comes from the attacker's own DNS/HTTP logs)8. Confirming Blind SSRF With Burp Collaborator
Burp Collaborator is an out-of-band interaction service built into Burp Suite. It issues a unique, attacker-controlled domain that can be planted into a suspected SSRF (or XXE, or header-injection) parameter, and then checked for any DNS, HTTP, or SMTP contact from the target.
Why it matters: blind SSRF produces no visible response — Collaborator solves this by acting as an independent listener that the vulnerable server will contact if the payload actually executes, proving the vulnerability is real and interactable rather than theoretical.
Step-by-step workflow:
- Burp menu → Collaborator client → "Copy to clipboard" — generates a unique subdomain such as
abcd1234.oastify.com. - Insert that domain into the suspected parameter, e.g.
POST /fetch?url=http://abcd1234.oastify.com/test. - Send the request through Repeater or Intruder.
- Return to the Collaborator client window and click "Poll now".
- Any DNS lookup, HTTP request, or SMTP connection from the target server appears in the Collaborator log, with full request details captured.
- A logged interaction confirms: the backend really did reach out to an attacker-controlled address.
Collaborator is also useful beyond confirming raw SSRF — it can reveal whether a URL parser follows redirects, whether an internal DNS resolver leaks internal hostnames even when the HTTP request fails, and whether SSRF is reachable indirectly through XXE, PDF generators, or image-processing libraries.
9. Typical Impact
- Cloud credential theft — reading AWS/GCP/Azure instance metadata to steal temporary IAM credentials, then pivoting into the cloud account.
- Internal reconnaissance / port scanning — using timing or error differences to map internal hosts and open ports.
- Access to internal-only services — admin panels, internal APIs, monitoring dashboards, and datastores (Redis, Elasticsearch) that trust "localhost."
- Remote code execution — hitting an unauthenticated internal Redis instance or an internal Jenkins/actuator endpoint as a stepping stone to full RCE.
- Firewall / ACL bypass — the request originates from a trusted internal server, not the attacker's IP.
- Denial of service — forcing large, slow, or repeated requests against the server itself.
- Data exfiltration — reading local files via
file://, where supported.
10. Prevention
Input & protocol validation:
- Whitelist, never blacklist — allow requests only to a pre-approved list of hosts or domains; blacklists are routinely bypassed via redirects, DNS rebinding, IPv6, or alternate IP notations.
- Restrict URL schemes to
http/httpsonly; explicitly blockfile://,gopher://,dict://, andftp://. - Parse and validate the URL structure rather than pattern-matching on a prefix.
Network-level controls:
- Resolve the hostname to an IP and reject private/reserved ranges (RFC1918, loopback, link-local
169.254.0.0/16) — then use that same resolved IP for the actual request, which defeats DNS rebinding. - Explicitly block the cloud metadata IP (
169.254.169.254), or require IMDSv2 on AWS, which needs a special token header and makes basic SSRF far harder to abuse. - Apply network segmentation so the server making outbound fetches has no route to sensitive internal systems it doesn't need.
- Disable automatic redirect-following in the server-side HTTP client, or re-validate the destination after every hop.
Application-level controls:
- Route outbound fetches through a dedicated, allowlisted proxy service instead of letting application code make arbitrary requests directly.
- Apply least privilege to the server's own credentials — if it must call a metadata service, scope IAM roles tightly so even a leak has minimal impact.
- Require authentication on internal services too — never rely on "it's internal, so it's safe."
- Log and monitor all outbound requests made by the server.
Defense-in-depth pipeline:
User Input → Validate URL (allowlist) → Restrict scheme (http/https only)
→ Resolve DNS, reject private/reserved IPs → Make request using the resolved IPUser Input → Validate URL (allowlist) → Restrict scheme (http/https only)
→ Resolve DNS, reject private/reserved IPs → Make request using the resolved IP
11. Practice Labs
Recommended hands-on resources, roughly ordered from easiest to hardest:
- PortSwigger Web Security Academy — SSRF (free): basic SSRF against the local server, SSRF with a blacklist-based filter, SSRF with a whitelist-based filter, SSRF via OpenID dynamic client registration, blind SSRF with out-of-band detection, and blind SSRF with Shellshock exploitation.
- HackTheBox — machines and challenges tagged SSRF, including internal metadata and Redis-pivoting scenarios.
- TryHackMe — rooms such as "SSRF" and internal-pivot exercises.
- DVWA / bWAPP — basic SSRF-style exercises, useful for fundamentals.
- OWASP Juice Shop — includes SSRF-adjacent challenges.
- HackerOne / Bugcrowd public disclosure reports — search "SSRF" for real-world writeups, best used after completing the labs above.
Conclusion
SSRF is deceptively simple to understand but easy to underestimate. At its core, it's just one broken assumption: trusting a URL supplied by someone else enough to let your own server fetch it. But that single assumption, left unchecked, can hand an attacker a direct line into everything your server can see — internal admin panels, private databases, and cloud credentials that were never meant to leave the network.
What makes SSRF particularly dangerous is its versatility. It doesn't need a flashy exploit or a zero-day — just a webhook field, an image importer, or a PDF generator that fetches URLs without asking where they're really pointing. And even when the response is invisible to the attacker, tools like Burp Collaborator prove that "blind" doesn't mean "safe."
The fix isn't complicated either: allowlist destinations instead of trying to blacklist bad ones, restrict schemes to http/https, re-resolve and pin IPs at request time, and never assume "internal" means "trusted." None of these are exotic controls — they're just discipline applied consistently.