OWASP Top 10 Security Lab

A10

Server-Side Request Forgery (SSRF)

Learn to exploit server-side request vulnerabilities and access internal services

What is Server-Side Request Forgery (SSRF)?

Server-Side Request Forgery (SSRF) occurs when an attacker can force a server-side application to make HTTP requests to an arbitrary domain of the attacker's choosing. This vulnerability allows attackers to access internal services, cloud metadata, and other restricted resources.

🎯 Common SSRF Attack Scenarios

  • Internal Service Access: Accessing internal APIs, databases, and administrative interfaces
  • Cloud Metadata Exploitation: Reading AWS/Azure/GCP instance metadata for credentials
  • Port Scanning: Discovering internal services and network topology
  • File System Access: Reading local files using file:// protocol
  • Bypassing Access Controls: Circumventing firewalls and network segmentation

🌐 Network Architecture

INTERNET → [WAF/Firewall] → [Web Server] → [Internal Network]

Vulnerable App
192.168.1.10:80
Admin Panel
192.168.1.50:8080
Database
192.168.1.100:3306
Metadata API
169.254.169.254:80

⚠️ Real-World Impact

  • Data Exfiltration: Accessing sensitive internal databases and APIs
  • Privilege Escalation: Gaining admin access to internal systems
  • Cloud Compromise: Stealing cloud credentials and escalating to full account takeover
  • Network Reconnaissance: Mapping internal infrastructure for further attacks
  • Denial of Service: Overloading internal services or external targets

🛡️ Prevention Strategies

  • Input Validation: Strict whitelist of allowed URLs and protocols
  • Network Segmentation: Isolate application servers from sensitive internal resources
  • Disable Unused Protocols: Block file://, gopher://, dict:// and other dangerous schemes
  • Response Filtering: Don't return raw response data to users
  • DNS Validation: Prevent DNS rebinding and private IP access
# Vulnerable SSRF Code def fetch_url(user_url): response = requests.get(user_url) # No validation! return response.text # Common SSRF Payloads http://192.168.1.50:8080/admin http://169.254.169.254/latest/meta-data/ file:///etc/passwd http://localhost:3306/ # Secure Implementation import ipaddress from urllib.parse import urlparse def fetch_url_secure(user_url): # Parse and validate URL parsed = urlparse(user_url) # Only allow HTTP/HTTPS if parsed.scheme not in ['http', 'https']: raise ValueError("Invalid protocol") # Resolve hostname to IP ip = socket.gethostbyname(parsed.hostname) # Block private/internal IPs if ipaddress.ip_address(ip).is_private: raise ValueError("Private IP not allowed") # Block localhost and metadata IPs blocked_ips = ['127.0.0.1', '169.254.169.254'] if ip in blocked_ips: raise ValueError("Blocked IP address") # Make request with timeout response = requests.get(user_url, timeout=5) return response.text[:1000] # Limit response size