Server-Side Request Forgery
Server-Side Request Forgery-Schwachstellen treten auf, wenn ein Benutzer eine Anwendung dazu veranlassen kann, HTTP-Anfragen an eine vom Angreifer festgelegte Domain zu senden. Wenn eine Anwendung Zugriff auf private oder interne Netzwerke hat, könnte ein Angreifer die Anwendung zudem dazu bringen, Anfragen an interne Server zu stellen.
Wir sehen uns dies anhand einiger Beispiele genauer an, um besser zu verstehen, wie dies in der Praxis aussieht.
Stellen Sie sich eine API vor, die eine URL von einem Benutzer entgegennimmt und ein Bild der bereitgestellten URL generiert, etwa für eine Vorschau oder den Export einer Seite.
ts
let url = request.params.url;
let response = http.get(url);
let render = response.render();
return render.export();
Da der URL-Parameter vom Benutzer gesteuert wird, kann ein Angreifer einfach auf jede beliebige URL zugreifen. In einigen Fällen, abhängig von der verwendeten Bibliothek für den URL-Zugriff, können sogar lokale Dateien über das „file://“-Schema aufgerufen werden.
Eine gängige Methode zur Ausnutzung einer SSRF-Schwachstelle bei Hosting auf AWS besteht darin, auf die AWS Metadata API zuzugreifen, die Anmeldedaten für die AWS API enthalten kann. Dies kann zu weiterem Zugriff auf andere AWS-Ressourcen innerhalb des Kontos führen, was, wie Sie sich vorstellen können, alles andere als ideal ist.
Risikominderung
Die Entschärfung von SSRF-Schwachstellen kann mitunter sehr schwierig sein und hängt stark davon ab, was der betreffende Code erreichen soll. Je nach Anforderung gibt es unterschiedliche Schutzmaßnahmen, die implementiert werden können.
Vermeidung von benutzerdefinierten URLs
In manchen Fällen können Sie eine Funktion so implementieren, dass sie nicht darauf angewiesen ist, dass ein Benutzer eine beliebige URL angibt. Wenn dies möglich ist, ist dies der effektivste Weg, um das SSRF-Risiko zu minimieren.
Funktionen minimieren
Wenn Sie eine PDF-Exportfunktion implementieren, neigt man vielleicht dazu, einfach einen Headless-Browser zu verwenden und einen Screenshot der Seite zu erstellen. Dies ist aufgrund der Komplexität von Browsern und der schieren Anzahl an Funktionen und Angriffsflächen, die Browser bieten, nicht immer ratsam.
Es ist wichtig, für die jeweilige Aufgabe das richtige Werkzeug zu verwenden. In manchen Fällen reicht ein einfacher HTTP-Client aus. Es gibt immer Möglichkeiten, die Funktionen und damit die verfügbaren Angriffsflächen bzw. Vektoren zu minimieren. Zum Beispiel bei einem HTTP-Client:
- Folgen von Weiterleitungen deaktivieren
- Alle Schemata außer HTTPS deaktivieren
Es gibt einige Fallstricke
Weiterleitungen & Iframes
Eine gängige Methode zum Schutz vor SSRF bei privaten Ressourcen (IP-Adressen oder interne Hostnamen) besteht darin, die vom Benutzer bereitgestellte URL zu parsen und eine „Deny-List“ zu verwenden, um den Zugriff auf sensible Ressourcen zu verhindern.
Es ist erwähnenswert, dass diese Methode in den meisten Fällen nicht effektiv ist, da sie in Szenarien umgangen werden kann, in denen der Client HTTP-Weiterleitungen, HTML/JavaScript-Weiterleitungen folgt oder komplexe Elemente wie Iframes rendern kann.
Ein Angreifer kann einer anfälligen Anwendung eine URL zu einer Seite bereitstellen, die auf eine sensible Ressource weiterleitet – sei es durch einen HTTP 301/302-Statuscode, eine HTML-Meta-Weiterleitung, das Setzen der aktuellen URL mittels Javascript beim Laden oder das Einbetten eines Iframes, der eine interne Ressource anzeigt. Dies umgeht effektiv jeden Versuch, die ursprüngliche URL zu validieren.
DNS-Rebinding
Eine weitere „Art“ der Umleitung kann auch über DNS erfolgen. Ein gängiger Versuch, SSRF-Angriffe zu verhindern, sieht wie folgt aus:
- Die bereitgestellte URL parsen
- Den Hostnamen extrahieren und eine DNS-Abfrage durchführen
- Die URL ablehnen, wenn sie in eine interne/private IP-Adresse aufgelöst wird, oder akzeptieren, wenn es sich um eine öffentliche IP-Adresse handelt
Diese Methode ist nicht wirklich effektiv, da sie anfällig für „DNS-Rebinding“ ist. DNS-Rebinding funktioniert aufgrund des Standardverhaltens der meisten Netzwerk-Stacks (wie etwa unter Linux und Windows), wenn eine TCP-Verbindung von einem Remote-Host geschlossen wird.
Wenn ein Remote-Host eine Verbindung gewaltsam schließt, versucht das System, die Verbindung nach einer erneuten DNS-Abfrage zur Auflösung der IP-Adresse wiederherzustellen.
Dies ermöglicht einem Angreifer Folgendes:
- Einen DNS-Eintrag für `rebinding.attacker.com` mit einer öffentlichen IP-Adresse erstellen, die einen offenen HTTP-Port und eine sehr kurze TTL (Time-to-Live) aufweist
- Die URL (Beispiel: https://rebinding.attacker.com/) an die anfällige Anwendung übermitteln. Diese prüft, ob die aufgelöste IP-Adresse privat ist – was nicht der Fall ist – und fährt in der Annahme, dass der Vorgang sicher ist, mit der angeforderten Operation fort
- Sobald die HTTP-Verbindung hergestellt ist, wird der DNS-Eintrag für „rebinding.attacker.com“ in eine interne IP-Adresse geändert
- Die HTTP-Verbindung wird gewaltsam geschlossen
- Dies veranlasst die Anwendung dazu, die IP-Adresse von „rebinding.attacker.com“ erneut aufzulösen, welche nun auf eine interne IP-Adresse zeigt
- Da die Schutzprüfung der IP-Auflösung bereits stattgefunden hat und die erneute DNS-Auflösung sowie der Verbindungsaufbau auf Kernel-Ebene erfolgen, bemerkt die Anwendung nicht, dass sich die IP-Adresse geändert hat
Dies umgeht effektiv den Schutz gegen die Angabe von URLs, die in private IP-Adressen aufgelöst werden.
IPv4 vs. IPv6
Eine weitere gängige Methode zur Umgehung von „Deny-Listen“ ist die Verwendung von IPv6. Da alle IPv4-Adressen als IPv6-Adressen dargestellt werden können, ist es oft möglich, Deny-Listen zu umgehen, indem man eine IPv6-Adresse verwendet, die auf die gewünschte IPv4-Adresse verweist.
Sichere Programmierung in der Praxis
Entdecken Sie Richtlinien für sicheres Programmieren, um Schwachstellen wie die OWASP Top 10 zu verstehen und zu beheben, und tauchen Sie in geführte Trainingsmissionen ein, um diese in realistischen Anwendungssimulationen zu üben.