When the server makes requests on the attacker's behalf
With server-side request forgery, an attacker tricks a server into making requests on their behalf against internal resources, such as cloud metadata endpoints or internal admin panels. We cover the typical entry points and how to validate target URLs with an allowlist instead of a blocklist.
Table of Contents
- 1. What Is Server-Side Request Forgery?
- 2. Common Entry Points in Applications
- 3. Cloud Metadata Endpoints as a Prime Target
- 4. Why a Pure Blocklist Is Not Enough
- 5. Network Level Hardening
- 6. Handling the Response Safely
- 7. A Code Review Checklist for SSRF
- 8. Common Mistakes When Securing SSRF
- 9. Best Practices and Checklist
- 10. Summary
- 11. FAQ
1. What Is Server-Side Request Forgery?
Server-side request forgery, or SSRF, happens when an application accepts a URL that a user can influence and then makes an HTTP request to that URL itself. Typical examples include webhook configuration, image import by URL, PDF generators that render an external page, or features that download a remote file on the server's behalf.
From the target system's point of view, the server acts as a trusted internal client. An attacker who controls the target URL can use that request to reach resources that would never be reachable from the outside, such as internal network segments, database admin interfaces, or cloud metadata services.
2. Common Entry Points in Applications
SSRF most commonly shows up in features that explicitly take a URL from the client: a webhook target, a profile picture import by link, a URL preview feature in a chat, or a PDF renderer that loads an external page as a template. Even seemingly harmless features like a link checker or an RSS feed import can enable SSRF if the target URL is not restricted.
The fixed version in the example below checks the host against a fixed allowlist, enforces HTTPS, resolves the hostname itself, and rejects private or reserved IP ranges to make DNS rebinding tricks harder. It also disables automatic redirects, since an attacker could otherwise use an allowed URL to redirect into an internal address.
<?php
declare(strict_types=1);
namespace App\Service;
use Symfony\Contracts\HttpClient\HttpClientInterface;
final class WebhookImageFetcher
{
private const ALLOWED_HOSTS = [
'images.trusted-partner.com',
'cdn.mironsoft.de',
];
public function __construct(
private readonly HttpClientInterface $httpClient,
) {
}
// Verwundbar: Jede vom Client übergebene URL wird direkt angefragt
public function fetchVulnerable(string $imageUrl): string
{
$response = $this->httpClient->request('GET', $imageUrl);
return $response->getContent();
}
// Abgesichert: Nur explizit erlaubte Hosts dürfen angefragt werden
public function fetchSecured(string $imageUrl): string
{
$host = parse_url($imageUrl, PHP_URL_HOST);
$scheme = parse_url($imageUrl, PHP_URL_SCHEME);
if ($scheme !== 'https' || $host === null || !\in_array($host, self::ALLOWED_HOSTS, true)) {
throw new \InvalidArgumentException('URL host is not on the allowlist.');
}
$ip = gethostbyname($host);
if ($this->isPrivateOrReservedIp($ip)) {
throw new \InvalidArgumentException('Resolved IP is not publicly routable.');
}
$response = $this->httpClient->request('GET', $imageUrl, [
'max_redirects' => 0,
]);
return $response->getContent();
}
private function isPrivateOrReservedIp(string $ip): bool
{
return filter_var(
$ip,
FILTER_VALIDATE_IP,
FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
) === false;
}
}
3. Cloud Metadata Endpoints as a Prime Target
A particularly popular SSRF target is cloud metadata services, reachable at a fixed link local address such as 169.254.169.254, which serve instance information without any authentication, sometimes including temporary credentials for the cloud API. If an attacker can get the server to request this address and return the response, they can potentially gain far-reaching access to the entire cloud infrastructure.
That is why explicitly blocking link local and private IP ranges is one of the most important SSRF mitigations, regardless of whether the application even runs in a cloud environment with a metadata service, since attack targets can change over the lifetime of the infrastructure.
4. Why a Pure Blocklist Is Not Enough
A blocklist that excludes known internal IP ranges like 127.0.0.1 or 10.0.0.0/8 looks sufficient at first glance, but it can be bypassed in many ways: through alternative IP notations such as octal or decimal encoding, through DNS rebinding, where a hostname first resolves to an allowed IP and later, after the check, to an internal IP, or through open redirects on allowed domains.
An allowlist of known, trusted target hosts avoids these problems fundamentally, because only explicitly approved targets are ever considered. Where a fixed allowlist is not feasible, for example with freely configurable customer webhook targets, the resolved IP address must additionally be validated immediately before the actual request to prevent DNS rebinding.
5. Network Level Hardening
Beyond application level validation, the server that performs outbound requests should be network segmented so it simply cannot reach internal systems like databases, admin panels, or cloud metadata services in the first place. A dedicated egress firewall rule for the outbound-facing service limits the damage even when an application level flaw gets overlooked.
In containerized environments, it also helps to run services that process external URLs in a separate, tightly restricted network namespace, so that even a successful SSRF attack hits a dead end because the target system is not reachable from that namespace at all.
6. Handling the Response Safely
The response of an SSRF-prone request also needs careful handling. If the full response body is returned to the client unfiltered, an attacker can effectively read out internal systems through the application itself, even when the request side is restricted by an allowlist.
A sensible approach limits the maximum response size, applies a timeout to the request, and checks the content type, so that an image import genuinely only accepts image data instead of passing through arbitrary text content.
7. A Code Review Checklist for SSRF
During code review, specifically search for functions that accept a URL, hostname, or IP address from user input and use it for an outbound HTTP request. For each of those functions, check whether an allowlist exists, whether redirects are controlled, and whether private IP ranges are excluded.
Pay particular attention to third party libraries, such as those used for PDF generation or URL previews, since they often bring their own HTTP clients that do not restrict redirects or internal addresses by default.
8. Common Mistakes When Securing SSRF
A common mistake is validating only the URL originally entered by the user, but not the actually resolved IP address, which leaves DNS rebinding fully possible. Another common mistake is following redirects unchanged, so a URL that was allowed at first can redirect into an internal address.
Placing too much trust in internal network components is also risky: even when a reverse proxy sits in front by default, the application itself should not make unchecked requests to arbitrary targets, since not every component along the chain is necessarily configured consistently.
9. Best Practices and Checklist
Every function that requests an external URL should validate against a fixed allowlist of hosts and schemes, validate the resolved IP address immediately before the request, and disable or tightly control automatic redirects.
It also helps to limit response size and timeout, segment the outbound-facing service at the network level, and specifically review third party libraries that bring their own HTTP client as part of a robust SSRF defense.
| Entry Point | Example | Risk | Mitigation |
|---|---|---|---|
| Webhook URL | Customer configures target URL freely | Access to internal services | Allowlist plus IP validation |
| Image import by URL | Load profile picture from external link | SSRF via image endpoint | Content type check, allowlist |
| PDF generator | Renders external page as a template | Access to cloud metadata | Block internal IP ranges |
| Link preview / RSS import | Target URL from user input | DNS rebinding | IP validation right before the request |
Mironsoft
Security audits, OWASP-compliant hardening, and secure architecture
Applications that actually hold up against a real attack attempt?
We review existing applications for classic OWASP vulnerabilities, insecure authentication, and missing input validation, then build an architecture that structurally reduces attack surface instead of just patching individual symptoms.
Security Audit
Systematically checking OWASP Top 10, auth flows, and input validation for vulnerabilities.
Secure Architecture
Building rate limiting, encryption, and access controls correctly from the ground up.
Incident Readiness
Establishing logging, monitoring, and response processes for when things go wrong.
10. Summary
SSRF
Root Cause
Server requests attacker-controlled URLs on its own behalf.
Detection
Code review for functions with user-controlled URLs.
Fix
Allowlist of approved hosts plus IP validation before the request.
Prevention
Network segmentation, redirect control, response limits.