Fix SSRF (Server Side Request Forgery) in Symfony
SSRF in Symfony applications typically occurs when the HttpClient component or native PHP streams are used to fetch a resource from a user-provided URL without strict validation. In cloud-native environments, this is a high-impact vulnerability that allows attackers to exfiltrate AWS/GCP metadata, bypass firewalls, or pivot into internal services like Redis or Memcached.
The Vulnerable Pattern
use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response;public function fetchMetadata(Request $request, HttpClientInterface $client): Response { // DANGER: User controls the full URL. // Attacker can pass ‘http://169.254.169.254/latest/meta-data/’ $url = $request->query->get(‘url’); $response = $client->request(‘GET’, $url);
return new Response($response->getContent());
}
The Secure Implementation
The fix focuses on three layers of defense. First, implement a strict domain allowlist using `parse_url`. Second, perform DNS resolution and use `FILTER_FLAG_NO_PRIV_RANGE` to block access to loopback (127.0.0.1) and private network ranges (10.0.0.0/8, etc.), which prevents attackers from hitting internal infrastructure. Third, disable redirects (`max_redirects => 0`) to stop an attacker from bypassing the initial check by redirecting a 'safe' URL to an internal one. For enterprise-grade security, consider using a dedicated egress proxy or the 'SafeCurl' pattern to prevent DNS rebinding attacks.
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Contracts\HttpClient\HttpClientInterface;public function fetchMetadata(string $url, HttpClientInterface $client): Response { $allowedDomains = [‘api.trusted-partner.com’]; $parts = parse_url($url);
if (!isset($parts['host']) || !in_array($parts['host'], $allowedDomains, true)) { throw new BadRequestHttpException('Domain not allowed'); } $ip = gethostbyname($parts['host']); if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { throw new BadRequestHttpException('Internal IPs are forbidden'); } // Use a scoped client or restricted transport to prevent protocol smuggling $response = $client->request('GET', $url, [ 'max_redirects' => 0, // Prevent redirect-based SSRF 'timeout' => 2.0 ]); return new Response($response->getContent());
}
Your Symfony API
might be exposed to SSRF (Server Side Request Forgery)
74% of Symfony apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.