Server-seitige Anforderungsfälschung
Server-Side Request Forgery-Schwachstellen treten auf, wenn ein Benutzer eine Anwendung dazu veranlassen kann, HTTP-Anfragen an eine vom Angreifer bestimmte Domäne zu stellen. Wenn eine Anwendung Zugang zu privaten/internen Netzwerken hat, könnte ein Angreifer die Anwendung auch dazu bringen, Anfragen an interne Server zu stellen.
Wir werden uns das anhand einiger Beispiele genauer ansehen, um besser zu verstehen, wie es in der Praxis aussieht.
Stellen Sie sich eine API vor, die eine URL von einem Benutzer entgegennimmt und ein Bild der vom Benutzer angegebenen URL generiert, z. B. 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 kontrolliert wird, kann ein Angreifer einfach auf jede beliebige URL zugreifen. In einigen Fällen kann es sich, je nach der für den Zugriff auf die URL verwendeten Bibliothek, sogar um lokale Dateien handeln, die das Schema "file://" verwenden.
Eine häufige Möglichkeit, eine SSRF-Schwachstelle zu missbrauchen, wenn sie in AWS gehostet wird, ist der Zugriff auf die AWS-Metadaten-API, die Anmeldeinformationen 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, nicht ideal ist.
Milderung
Die Abschwächung von SSRF-Schwachstellen kann mitunter sehr schwierig sein und hängt stark davon ab, was der betreffende Code erreichen soll. Je nach den Anforderungen gibt es verschiedene Abhilfemaßnahmen, die eingesetzt werden können.
Vermeiden Sie benutzerdefinierte URLs
In manchen Fällen können Sie eine Funktion so implementieren, dass sie nicht auf die Angabe einer beliebigen URL durch den Benutzer angewiesen ist. Wenn dies überhaupt möglich ist, ist dies die effektivste Art, das Risiko von SSRF zu verringern.
Fähigkeiten minimieren
Wenn Sie eine PDF-Exportfunktion implementieren, könnte man geneigt sein, einfach einen Browser ohne Kopf zu verwenden und einen Screenshot der Seite zu machen. Angesichts der Komplexität von Browsern und der schieren Anzahl von Funktionen und Angriffsflächen, die Browser bieten, ist dies nicht immer ratsam.
Es ist wichtig, das richtige Werkzeug für die jeweilige Aufgabe zu verwenden. In manchen Fällen ist ein einfacher HTTP-Client ausreichend. Es gibt immer Dinge, die man tun kann, um die Fähigkeiten und damit die Angriffsfläche/Vektoren zu minimieren. Zum Beispiel im Falle eines HTTP-Clients:
- Deaktivieren Sie die folgenden Weiterleitungen
- Deaktivieren Sie alle anderen Verfahren als HTTPS
Es gibt einige Fallstricke
Umleitungen & iframes
Eine gängige Methode zum Schutz vor SSRF auf privaten Ressourcen (IP-Adressen oder interne Hostnamen) besteht darin, die von einem Benutzer angegebene URL zu analysieren und eine "Deny-Liste" 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-Redirects, HTML/JavaScript-Redirects folgt oder komplexe Elemente wie Iframes rendern kann.
Ein Angreifer kann einer anfälligen Anwendung, die eine Seite hostet, eine URL zur Verfügung stellen, die zu einer sensiblen Ressource umleitet, entweder durch eine HTTP 301/302, eine HTML-Meta-Umleitung, das Setzen der aktuellen URL mit Javascript beim Laden oder das Einbetten eines Iframe, der eine interne Ressource zeigt. Auf diese Weise wird jeder Versuch umgangen, die ursprüngliche URL zu validieren.
DNS-Neubindung
Eine andere "Art" der Umleitung kann auch über DNS erfolgen. Eine gängige Methode, um SSRF-Angriffe zu verhindern, ist die folgende:
- Parsen Sie die angegebene URL
- Nehmen Sie den Hostnamen und führen Sie eine DNS-Suche durch
- Ablehnung der URL, wenn sie zu einer internen/privaten IP aufgelöst wird, oder Annahme der URL, wenn es sich um eine öffentliche IP handelt
Diese Methode ist nicht wirklich effektiv, da sie anfällig für "DNS Rebinding" ist. DNS Rebinding funktioniert aufgrund des Standardverhaltens der meisten Netzwerkstacks (z. B. von Linux und Windows), wenn eine TCP-Verbindung von einem entfernten Host geschlossen wird.
Wenn ein entfernter Host eine Verbindung gewaltsam schließt, versucht er, die Verbindung wiederherzustellen, nachdem er eine weitere DNS-Abfrage durchgeführt hat, um die IP-Adresse neu aufzulösen.
Dadurch kann ein Angreifer Folgendes tun:
- Erstellen eines DNS-Eintrags für "rebinding.attacker.com" mit einer öffentlichen IP-Adresse und einem offenen HTTP-Port mit einer sehr kurzen TTL (Time-to-live)
- Übermitteln Sie die URL (Beispiel: https://rebinding.attacker.com/) an die anfällige Anwendung. Sie prüft, ob die aufgelöste IP-Adresse nicht privat ist, was nicht der Fall ist, und führt dann die angeforderte Operation in dem Glauben durch, dass sie sicher ist
- 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 zwangsweise geschlossen
- Dies führt nun dazu, dass die Anwendung die IP-Adresse von "rebinding.attacker.com" neu auflöst, die nun auf eine interne IP-Adresse zeigt
- Da der Schutz der IP-Auflösung bereits stattgefunden hat und die erneute Auflösung des DNS-Eintrags und die erneute Verbindungsaufnahme im Kernel erfolgen, ist der Anwendung nicht bewusst, dass sich die IP nun geändert hat.
Dadurch wird der Schutz vor der Bereitstellung von URLs, die zu privaten IP-Adressen führen, effektiv umgangen.
IPv4 vs. IPv6
Eine weitere gängige Methode zur Umgehung von Deny-Listen ist die Verwendung von IPv6. Da alle IPv4-Adressen in Form einer IPv6-Adresse ausgedrückt werden können, ist es oft möglich, Deny-Listen zu umgehen, indem man eine IPv6-Adresse verwendet, die auch einer IPv4-Adresse entspricht, auf die man zugreifen möchte.