Das Security Research Team von JFrog ist ständig auf der Suche nach bisher unbekannten Schwachstellen und Sicherheitsproblemen in beliebten Open-Source-Projekten, um die Sicherheitslage zu verbessern und die gesamte Software-Lieferkette zu schützen. Als Teil dieser Bemühungen wurden vor kurzem mehrere Schwachstellen in beliebten Rust-Projekten wie Axum, Salvo und Conduit-Hyper entdeckt, die auf die gleiche Ursache zurückzuführen sind – nämlich angemessene Grenzen für HTTP-Anfragen zu setzen, wenn die Hyper-Bibliothek verwendet wird.
Was ist das Hyper-Paket von Rust?
Hyper ist eine äußerst beliebte, in Rust geschriebene HTTP-Bibliothek auf niedriger Ebene. Die Bibliothek ist kein vollwertiger HTTP-Server oder -Client, sondern kann als „Baustein“ für die Implementierung verwendet werden, da sie Methoden für die Beantwortung von Anfragen, das Parsen von Anfragekörpern und die Generierung korrekter HTTP-Antworten enthält. Derzeit ist dies die beliebteste HTTP-Bibliothek von Rust, die aufgrund ihrer Nützlichkeit für die Erstellung von funktionsreicheren HTTP-Clients und -Servern mehr als 67 Millionen Mal von crates.io heruntergeladen wurde. Zwei der beliebtesten Rust-basierten HTTP-Clients und -Server, nämlich reqwest und warp, basieren auf Hyper, und insgesamt gibt es derzeit 2579 Projekte in crates.io, die von Hyper abhängen.
Die grundlegende Schwachstelle – unbegrenzter Ressourcenverbrauch
Eine sehr verbreitete und nützliche Funktion in der Hyper-API ist body::to_bytes, die Funktion wird zum Kopieren eines Request- oder Response-Bodys in einen einzelnen Byte-Puffer verwendet. Die Unsicherheit besteht hierbei darin, dass die Funktion keine Längenprüfungen durchführt. Da die Funktion den gesamten Body in einen einzigen Puffer schreibt, kann die Funktion dazu gebracht werden, eine beliebige Menge an Speicher zuzuweisen, die direkt proportional zur Größe eines manipulierten HTTP-Pakets ist.
Das Problem – sofortiger DoS-Angriff
Einige Anbieter haben diese Warnung ignoriert oder das Problem einfach heruntergespielt, da das Senden einer einzelnen HTTP-Anfrage mit einer Body-Größe von 64 GB ziemlich unwahrscheinlich erscheint – die übertragene Datenmenge wäre enorm, und in der realen Welt würde diese Anfrage von Proxies, CDNs, WAFs und anderen allein aufgrund ihrer abnormen Größe gestoppt werden. Ohne jegliche Längenprüfung ist es jedoch möglich, diese Sicherheitslücke zu missbrauchen, um DoS-Angriffe selbst mit einem sehr kleinen Paket zu initiieren. Die Funktion „body::to_bytes“ liest to_bytes-Datenpakete. Wenn nun nur ein Chunk vorhanden ist, gibt sie diesen einfach zurück. Nach dem Lesen des ersten Chunks prüft der Code, ob es noch mehr zu lesen gibt. Wartet nichts anderes auf der Zeile, gibt er das erste gelesene Stück zurück. Stehen mehr Daten in der Zeile, erstellt er einen Vektor mit einer Kapazität, die der erwarteten Länge des Körpers entspricht.
Der Code füllt dann den Vektor mit den bereits gelesenen Daten und wartet dann darauf, dass die restlichen Daten in den Vektor eingelesen werden. Entscheidend ist dabei, dass die Größe des Vektors aus dem „Content-Length“-Header abgeleitet wird. Die erwartete Größe wird direkt an die Speicherzuweisung von Rust weitergegeben. Wenn die erwartete Größe für die Speicherzuweisung zu groß ist, gerät das System in Panik und bringt den Prozess zum Absturz. Je nach dem Projekt, das Hyper verwendet, könnte ein Zero-Click-DoS-Angriff häufig einen solchen Absturz verursachen, da das Szenario, dass ein HTTP-basierter Server Daten aus nicht vertrauenswürdigen Quellen erhält, sehr häufig vorkommt. Ein solcher Fall betrifft das Axum-Webanwendungs-Framework, bei dem jede mit dem Framework erstellte Webanwendung standardmäßig für diese Schwachstelle anfällig ist.
Wie kann dieses Problem behoben werden?
Da die Hyper-Bibliothek die Größe des HTTP-Bodys nicht standardmäßig einschränkt, liegt es an den Entwicklern, die sich auf Hyper verlassen, die Größenprüfung in ihrem eigenen Code zu implementieren, indem man den „size_hint“ der Anfrage/Antwort mit einer Obergrenze vergleicht.
Fazit
Zusammenfassend lässt sich sagen, dass das Fehlen von Größenbeschränkungen bei der Verwendung von Hyper eine sehr ernste Sicherheitslücke darstellt, das von Angreifern leicht ausgenutzt werden kann, um sowohl HTTP-Clients als auch Server zum Absturz zu bringen. Die Sicherheitsforscher von JFrog empfehlen dringend, eine Speichergrößenbegrenzung in diesem Prozess zu implementieren. Das Security Research Team wird auch in Zukunft Rust-Maintainer alarmieren, die für solche Schwachstellen anfällig sind, so dass alle Instanzen behoben werden können.
www.research.jfrog.com