Defense Against SSRF: Hardening Laravel Outgoing Requests
SSRF allows attackers to force your server to make unauthorized requests. Learn to secure your Laravel application by validating URLs and restricting targets.
Previously in this course, we discussed multi-tenant security, focusing on isolating data at the database level. Today, we shift our focus from incoming data to outgoing traffic. Server-Side Request Forgery (SSRF) occurs when an attacker influences an application to fetch resources from internal or unauthorized external locations, essentially turning your server into a proxy for malicious activity.
In our SaaS project, we frequently fetch metadata or webhooks for users. Left unchecked, a user could provide an internal IP address (like 169.254.169.254) to exfiltrate cloud credentials or scan your internal microservices.
Understanding the SSRF Attack Vector
At its core, SSRF exploits the trust your internal network places in your web servers. Because your server resides within a VPC or a private network, it often has access to services that are not exposed to the public internet.
When you use Http::get($userProvidedUrl), Laravel performs a DNS resolution and initiates a connection. If an attacker provides a URL targeting your internal Redis instance or a management interface, your server will dutifully execute that request, potentially leaking sensitive information or triggering unintended state changes.
Hardening Outgoing Requests
To defend against SSRF, we must treat all user-provided URLs as inherently hostile. We do this through three layers of defense:
- Strict URL Validation: Use regex and PHP's
filter_varto ensure the URL follows expected patterns. - Allow-listing: Limit requests to known, trusted domains.
- Network Isolation: Block access to loopback addresses (
127.0.0.1) and private IP ranges (e.g.,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16).
Worked Example: The Secure Fetcher Service
Instead of calling the Http facade directly in our controllers, we will encapsulate this logic in a dedicated service. This ensures that every outgoing request passes through our security filters.
PHPnamespace App\Services; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; use InvalidArgumentException; class SecureHttpClient { private const ALLOWED_HOSTS = ['api.trusted-partner.com', 'webhooks.customer.com']; public function get(string $url) { $parsed = parse_url($url); #6A9955">// 1. Validate the host is in our allowed list if (!in_array($parsed['host'] ?? '', self::ALLOWED_HOSTS)) { throw new InvalidArgumentException("Unauthorized destination host."); } #6A9955">// 2. Resolve the IP to prevent DNS Rebinding attacks $ip = gethostbyname($parsed['host']); if ($this->isInternalIp($ip)) { throw new InvalidArgumentException("Internal network access prohibited."); } return Http::get($url); } private function isInternalIp(string $ip): bool { return !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE); } }
Hands-on Exercise
- Create a new
App\Services\SecureHttpClientclass in your project. - Implement a
validateUrlmethod that checks forhttporhttpsschemes only. - Integrate this service into your existing webhook-processing logic (advancing our SaaS project's integration module).
- Write a test case that attempts to hit
http://127.0.0.1and asserts that it throws anInvalidArgumentException.
Common Pitfalls
- Trusting DNS: Attackers can use DNS rebinding to bypass initial checks. Always resolve the domain to an IP address before making the request and validate that specific IP.
- Following Redirects: By default, many HTTP clients (including Guzzle, which Laravel uses) follow redirects. If you validate the first URL but the response redirects to an internal IP, you remain vulnerable. Ensure you disable automatic redirects or validate the final destination URL.
- Ignoring IPv6:
FILTER_VALIDATE_IPcan be tricky with IPv6 addresses. Ensure your validation logic covers both protocol versions.
Summary
Securing your infrastructure against SSRF is not just about blocking IP addresses; it's about adopting a "zero-trust" approach to your own egress traffic. By validating the target host and checking the resolved IP address before initiating the request, you effectively neutralize the most common vectors for this vulnerability.
As we continue to harden our architecture, remember that preventing blind SSRF is equally important if your application interacts with cloud metadata services.
Up next: We will discuss Mass Assignment Hardening, ensuring that your models are protected from malicious attribute injection.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs โ the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

FilamentPHP Admin Panel & Dashboard Development
A powerful admin panel for your Laravel app โ built with FilamentPHP so you can manage everything without touching the database.