Looking for the vulnerability index of Invicti's legacy products?
Server-Side Request Forgery - Vulnerability Database

Server-Side Request Forgery

Description

Server-Side Request Forgery (SSRF) is a vulnerability that allows an attacker to manipulate a server into making unintended HTTP requests on their behalf. Attackers can abuse this to access internal services, scan internal networks, bypass firewall restrictions, or interact with services on the localhost interface that would otherwise be inaccessible from the internet. This occurs when applications accept user-supplied URLs or hostnames without proper validation and use them to initiate server-side requests.

Remediation

Implement comprehensive input validation and security controls to prevent SSRF attacks:

1. Use an allowlist approach: Only permit requests to explicitly approved domains, IP addresses, or URL patterns. Reject all others by default.

2. Validate and sanitize all user input: Parse URLs completely and validate each component (protocol, hostname, port, path). Reject private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), localhost (127.0.0.0/8, ::1), link-local addresses (169.254.0.0/16), and cloud metadata endpoints (169.254.169.254).

3. Disable unnecessary URL schemas: Only allow http:// and https:// protocols. Block file://, gopher://, ftp://, and other potentially dangerous schemes.

4. Implement network segmentation: Isolate services that make external requests from critical internal systems. Use separate network zones with strict firewall rules.

5. Use DNS resolution carefully: Resolve hostnames and check the resulting IP address against blocklists before making requests to prevent DNS rebinding attacks.

Example validation code (Python):

import ipaddress
from urllib.parse import urlparse

def is_safe_url(url):
    try:
        parsed = urlparse(url)
        
        # Only allow HTTP/HTTPS
        if parsed.scheme not in ['http', 'https']:
            return False
        
        # Resolve and check IP address
        ip = ipaddress.ip_address(socket.gethostbyname(parsed.hostname))
        
        # Block private/internal ranges
        if ip.is_private or ip.is_loopback or ip.is_link_local:
            return False
        
        # Check against allowlist
        allowed_domains = ['api.trusted-service.com', 'cdn.example.com']
        if parsed.hostname not in allowed_domains:
            return False
            
        return True
    except:
        return False

Related Vulnerabilities