---
title: Protect Against SSRF Attacks
impact: MEDIUM
impactDescription: prevents attackers from making requests from your server to internal services
tags: ssrf, url, network, internal, security, php
---

## Protect Against SSRF Attacks

Server-Side Request Forgery (SSRF) allows an attacker to force your server to make requests to internal services, local files, or cloud metadata endpoints (e.g., AWS metadata). This often happens when the application takes a URL from a user and fetches its content.

**Incorrect (accepting user URLs without validation):**

```php
// SSRF vulnerability using file_get_contents
$url = $_GET['url'];
echo file_get_contents($url); // Attacker: ?url=http://169.254.169.254/latest/meta-data/

// SSRF via cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_GET['url']);
curl_exec($ch);
```

**Correct (strict validation and blocklists):**

```php
$userUrl = $_GET['url'];
$parsed = parse_url($userUrl);

// 1. Force protocol (Whitelist)
$allowedProtocols = ['http', 'https'];
if (!in_array($parsed['scheme'], $allowedProtocols)) {
    die("Only HTTP/HTTPS allowed");
}

// 2. Host Whitelist (Most Secure)
$allowedHosts = ['api.trusted.com', 'images.trusted.com'];
if (!in_array($parsed['host'], $allowedHosts)) {
    die("Untrusted host");
}

// 3. Block Private/Internal IP Ranges (If dynamic hosts are required)
$ip = gethostbyname($parsed['host']);
$privateRanges = [
    '127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', 
    '192.168.0.0/16', '169.254.169.254' // AWS Metadata
];
// Use a library like `spatie/ip-range-check` to verify $ip against $privateRanges

// 4. Safe cURL usage
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $userUrl);
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); // Restrict protocols
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); // Disable redirects to prevent bypass
curl_exec($ch);
```

**Prevention Checklist:**
- **Whitelisting**: Only allow requests to specific, trusted domains.
- **Protocol Restriction**: Only allow `http` or `https`. Disable `file://`, `gopher://`, `dict://`, etc.
- **Network Isolation**: Ensure your web server cannot reach internal databases or management interfaces directly.
- **Authentication**: Require identification for any proxying service.

**Tools:** PHP `parse_url()`, cURL security options, SonarQube, Manual Security Review
