Bei einem SSRF-Angriff greift der Angreifer die Maschine, auf die er es abgesehen hat, nicht direkt an: Er benutzt die Website als Mittelsmann. Der Webserver steht oft in einem Netzwerk, in dem er Dienste erreicht, die aus dem Internet niemand erreichen dürfte. Ruft eine Funktion der Website eine vom Benutzer gelieferte URL ab, ohne das Ziel zu prüfen, kann der Angreifer sie diese Dienste in seinem Auftrag abfragen lassen. OWASP hat SSRF in den Top 10 von 2021 eine eigene Kategorie gegeben (A10), und MITRE führt die Schwachstelle als CWE-918.
So funktioniert ein SSRF-Angriff
Gefährdet sind Funktionen, die eine URL abrufen: ein Bild von einer Adresse importieren, eine Linkvorschau erzeugen, einen Webhook aufrufen, einen Feed prüfen. Der Angreifer schiebt statt einer öffentlichen Adresse eine interne unter:
- den Metadatendienst der Cloud unter
169.254.169.254, genutzt von AWS, Azure und Google Cloud, der Zugangsdaten und Zugriffstokens preisgeben kann; - den Server selbst (
localhost,127.0.0.1), zum Beispiel eine Verwaltungsoberfläche oder eine Datenbank, die nur lokal lauscht; - das private Netzwerk (
10.0.0.0/8,192.168.0.0/16…), um Rechner und offene Ports zu kartieren; - andere Protokolle als HTTP wie
file://odergopher://, wenn die verwendete Bibliothek sie akzeptiert.

Die Antwort kommt nicht immer vollständig zurück: Man spricht von „blinder“ SSRF, wenn der Angreifer nur eine Fehlermeldung oder eine Antwortzeit sieht. Das reicht trotzdem, um zu erkennen, ob ein Port offen ist.
So schützt du dich
- Allowlist: Wenn die Ziele bekannt sind (eine bestimmte API), akzeptiere nur diese.
- Nur http und https, auf den Standardports.
- Interne Adressen ablehnen, und zwar nach der DNS-Auflösung, und auch jede Weiterleitung prüfen: Ein öffentlicher Domainname kann auf eine private Adresse zeigen.
- Auf Hosting-Seite: Netzwerksegmentierung und bei AWS der Wechsel zu IMDSv2, den OWASP empfiehlt, um den Diebstahl von Metadaten zu erschweren.
Für WordPress: wp_safe_remote_get und Pingbacks
WordPress bringt die richtigen Werkzeuge mit, sofern du sie nutzt. wp_safe_remote_get() und seine Varianten prüfen die URL und jede Weiterleitungs-URL mit wp_http_validate_url(): Nur http und https sind erlaubt, Zugangsdaten in der URL werden abgelehnt, Loopback- und private Adressen zurückgewiesen, und ein angegebener Port muss 80, 443 oder 8080 sein. wp_remote_get() dagegen führt diese Prüfung standardmäßig nicht durch: Ein Plugin, das damit eine vom Besucher gelieferte URL abruft, ist angreifbar. Mit dem Filter http_request_host_is_external kannst du einen bestimmten internen Host erlauben; ihn für alles zu öffnen, hebelt den Schutz aus.
$response = wp_safe_remote_get( esc_url_raw( $supplied_url ), array( 'timeout' => 5 ) );
if ( is_wp_error( $response ) ) {
return; // URL abgelehnt oder nicht erreichbar
}
Der Core selbst hatte dieses Problem schon einmal: Vor WordPress 3.5.1 ließ sich der Pingback von XML-RPC nutzen, um Anfragen an interne Server zu schicken und Ports zu scannen (CVE-2013-0235). Pingbacks verwenden heute wp_safe_remote_get(), bleiben aber eine Funktion, die deinen Server auf Wunsch eines Dritten Anfragen senden lässt. Wenn du sie nicht nutzt, blockiert das Härtungsmodul von WP Masquerade kostenlos Pingbacks und XML-RPC; unser Beitrag zu XML-RPC hilft dir zu prüfen, dass kein Dienst darauf angewiesen ist. Ansonsten muss SSRF im Code des betroffenen Plugins behoben werden, und eine Web Application Firewall kann bis dahin die offensichtlichsten internen Adressen filtern.