Server-Side Request Forgery (SSRF)
Beschreibung
Server-Side Request Forgery (SSRF) tritt auf, wenn eine Webanwendung eine Remote-Ressource abruft, ohne die vom Benutzer bereitgestellte URL zu validieren. Dies ermöglicht es Angreifern, die Anwendung zu zwingen, Anfragen an ein unerwartetes Ziel zu senden, selbst wenn es durch eine Firewall, ein VPN oder eine Netzwerk-Zugriffskontrollliste geschützt ist. Angreifer können SSRF missbrauchen, um auf interne Dienste, Cloud-Metadaten-Endpunkte zuzugreifen, lokale Dateien zu lesen (mit dem file://-Protokoll), interne Netzwerke zu scannen oder mit internen APIs zu interagieren. SSRF ist mit Cloud-Deployments zunehmend kritisch geworden, da Metadaten-Dienste sensible Anmeldedaten enthalten.
Risiko
SSRF ist in den CWE Top 25 und OWASP Top 10 aufgeführt. CVE-2024-43394 im Apache HTTP Server ermöglicht SSRF, das SMB-Verbindungen zu angreifergesteuerten Hosts auslöst und NTLM-Authentifizierungs-Hashes für Offline-Cracking oder Relay-Angriffe erfasst. CVE-2025-59775 im Apache HTTP Server ermöglicht SSRF, wenn AllowEncodedSlashes aktiviert ist. CVE-2025-47437 in LiteSpeed Cache ermöglicht authentifizierten Benutzern, serverseitige Anfragen an interne Ressourcen zu stellen. Der Capital-One-Breach nutzte SSRF aus, um auf AWS-Metadaten-Dienste zuzugreifen und über 100 Millionen Datensätze offenzulegen. Tesla-Cryptojacking-Vorfälle nutzten SSRF, um auf interne Cloud-Infrastruktur zuzugreifen.
Lösung
Validieren und sanitisieren Sie alle vom Benutzer bereitgestellten URLs. Implementieren Sie Allowlists für erlaubte Domains und Protokolle. Blockieren Sie Anfragen an private IP-Bereiche (10.x.x.x, 172.16-31.x.x, 192.168.x.x, 127.x.x.x, 169.254.x.x). Deaktivieren Sie unnötige URL-Schemata (file://, gopher://, dict://). Verwenden Sie DNS-Auflösungsvalidierung, um DNS-Rebinding zu verhindern. Implementieren Sie Netzwerksegmentierung, um die SSRF-Auswirkungen zu begrenzen. Blockieren Sie den Zugriff auf Cloud-Metadaten-Endpunkte (169.254.169.254). Verwenden Sie IMDSv2 auf AWS, das Session-Tokens erfordert. Überwachen Sie ungewöhnliche ausgehende Verbindungen.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Interne Datenoffenlegung Angreifer können Daten von internen Diensten, Cloud-Metadaten und lokalen Dateien lesen. |
| Integrität | Bereich: Manipulation interner Dienste SSRF kann verwendet werden, um Daten auf internen Diensten zu modifizieren oder Aktionen auszulösen. |
| Zugriffskontrolle | Bereich: Firewall-Umgehung Angreifer umgehen Netzwerk-Sicherheitskontrollen, indem sie den Server als Proxy verwenden. |
Beispielcode + Lösungscode
Anfälliger Code
# ANFÄLLIG: Abrufen einer vom Benutzer bereitgestellten URL ohne Validierung
import requests
from flask import Flask, request
@app.route('/fetch')
def fetch_url():
url = request.args.get('url')
# Angreifer gibt an: url=http://169.254.169.254/latest/meta-data/
# Server ruft AWS-Metadaten mit Anmeldedaten ab!
response = requests.get(url)
return response.text
# ANFÄLLIG: Webhook ohne URL-Validierung
@app.route('/webhook', methods=['POST'])
def create_webhook():
webhook_url = request.json['callback_url']
# Speichern und später diese URL aufrufen - könnte interner Dienst sein!
save_webhook(webhook_url)
return 'Webhook registriert'
# ANFÄLLIG: Bild-Proxy ohne Validierung
@app.route('/proxy/image')
def proxy_image():
image_url = request.args.get('url')
response = requests.get(image_url)
return response.content, 200, {'Content-Type': 'image/png'}
// ANFÄLLIG: URL-Abruf ohne Validierung
@RestController
public class UrlFetcherController {
@GetMapping("/fetch")
public String fetchUrl(@RequestParam String url) throws Exception {
// Angreifer: url=file:///etc/passwd
URL urlObj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
return new String(conn.getInputStream().readAllBytes());
}
}
// ANFÄLLIG: PDF-Generator mit externen Ressourcen
@PostMapping("/generate-pdf")
public byte[] generatePdf(@RequestBody PdfRequest request) {
// Angreifer fügt ein: <img src="http://internal-api/admin/users">
// PDF-Engine ruft interne URL ab!
return pdfGenerator.generate(request.getHtml());
}
Korrigierter Code
# SICHER: URL-Validierung mit Allowlist und Blocklist
import requests
import ipaddress
from urllib.parse import urlparse
import socket
ALLOWED_SCHEMES = {'http', 'https'}
ALLOWED_DOMAINS = {'api.example.com', 'cdn.example.com'}
BLOCKED_IP_RANGES = [
ipaddress.ip_network('10.0.0.0/8'),
ipaddress.ip_network('172.16.0.0/12'),
ipaddress.ip_network('192.168.0.0/16'),
ipaddress.ip_network('127.0.0.0/8'),
ipaddress.ip_network('169.254.0.0/16'), # AWS-Metadaten
ipaddress.ip_network('0.0.0.0/8'),
]
def is_safe_url(url):
"""Validiert, ob URL sicher abgerufen werden kann."""
try:
parsed = urlparse(url)
# Schema prüfen
if parsed.scheme not in ALLOWED_SCHEMES:
return False, "Ungültiges Schema"
# Gegen Allowlist prüfen (wenn Allowlist-Ansatz verwendet wird)
if ALLOWED_DOMAINS and parsed.hostname not in ALLOWED_DOMAINS:
return False, "Domain nicht erlaubt"
# Hostname zu IP auflösen und gegen Blocklist prüfen
try:
ip = ipaddress.ip_address(socket.gethostbyname(parsed.hostname))
except (socket.gaierror, ValueError):
return False, "Hostname kann nicht aufgelöst werden"
for blocked_range in BLOCKED_IP_RANGES:
if ip in blocked_range:
return False, "IP-Adresse blockiert"
return True, None
except Exception as e:
return False, str(e)
@app.route('/fetch')
def fetch_url_safe():
url = request.args.get('url')
is_safe, error = is_safe_url(url)
if not is_safe:
return f'Ungültige URL: {error}', 400
# Timeout verwenden und Weiterleitungen deaktivieren, um SSRF via Redirect zu verhindern
response = requests.get(url, timeout=5, allow_redirects=False)
# Bei Weiterleitung erneut validieren
if response.is_redirect:
return 'Weiterleitungen nicht erlaubt', 400
return response.text
// SICHER: URL-Validierung mit IP-Blocklist
@RestController
public class SecureUrlFetcherController {
private static final Set<String> ALLOWED_SCHEMES = Set.of("http", "https");
private static final List<String> BLOCKED_PREFIXES = List.of(
"10.", "172.16.", "172.17.", "172.18.", "172.19.",
"172.20.", "172.21.", "172.22.", "172.23.", "172.24.",
"172.25.", "172.26.", "172.27.", "172.28.", "172.29.",
"172.30.", "172.31.", "192.168.", "127.", "169.254.", "0."
);
@GetMapping("/fetch")
public String fetchUrlSafe(@RequestParam String url) throws Exception {
URL urlObj = new URL(url);
// Schema validieren
if (!ALLOWED_SCHEMES.contains(urlObj.getProtocol().toLowerCase())) {
throw new SecurityException("Ungültiges URL-Schema");
}
// IP auflösen und validieren
InetAddress address = InetAddress.getByName(urlObj.getHost());
String ip = address.getHostAddress();
for (String prefix : BLOCKED_PREFIXES) {
if (ip.startsWith(prefix)) {
throw new SecurityException("Blockierte IP-Adresse");
}
}
// Zusätzliche Prüfung auf Loopback
if (address.isLoopbackAddress() || address.isLinkLocalAddress()) {
throw new SecurityException("Lokale Adressen nicht erlaubt");
}
// Mit Timeout abrufen
HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.setInstanceFollowRedirects(false);
return new String(conn.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
}
}
Ausgenutzt in der Praxis
Capital One Datenleck (Capital One, 2019)
Angreifer nutzten SSRF über eine fehlkonfigurierte WAF aus, um auf AWS-Metadaten-Dienste unter 169.254.169.254 zuzugreifen und IAM-Anmeldedaten abzurufen, die Zugang zu S3-Buckets mit persönlichen Informationen von über 100 Millionen Kunden ermöglichten.
Apache HTTP Server NTLM-Hash-Erfassung (Apache, 2024)
CVE-2024-43394 im Apache HTTP Server 2.4.0-2.4.63 unter Windows ermöglicht SSRF, das SMB-Verbindungen zu angreifergesteuerten Hosts auslöst und die Erfassung von NTLM-Authentifizierungs-Hashes zum Cracken oder für Relay-Angriffe ermöglicht.
LiteSpeed Cache SSRF (LiteSpeed, 2025)
CVE-2025-47437 in LiteSpeed Cache bis 7.0.1 ermöglicht authentifizierten Benutzern mit niedrigen Privilegien, serverseitige Anfragen an interne oder externe Ressourcen ohne Benutzerinteraktion zu stellen.
Tools zum Testen/Ausnutzen
-
SSRFmap - Automatisiertes SSRF-Ausnutzungstool.
-
Gopherus - Gopher-Payloads für SSRF generieren.
-
Burp Collaborator - Blind SSRF erkennen.
CVE-Beispiele
-
CVE-2024-43394 - Apache HTTP Server SSRF zu SMB.
-
CVE-2025-47437 - LiteSpeed Cache SSRF.
-
CVE-2021-21972 - VMware vCenter Server SSRF zu RCE.
Referenzen
-
MITRE. "CWE-918: Server-Side Request Forgery (SSRF)." https://cwe.mitre.org/data/definitions/918.html
-
OWASP. "Server-Side Request Forgery Prevention Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html