← Zurück zur Übersicht

Ein Zufallswert hat die Admin-Tür aufgemacht. Einen Tag nach der Anleitung kamen die Angreifer

Letzte Woche ging eine Lücke durch die Sicherheitsnews, bei der ich beim Lesen kurz schlucken musste, weil der Fehler so banal ist. Es geht um Rejetto HFS, einen kleinen Dateiserver, der auf Node läuft. Der hat den Schlüssel, mit dem er seine Login-Cookies signiert, aus Math.random() gebaut. Also aus der Funktion, die man nimmt, wenn ein Ladebalken ein bisschen zufällig zappeln soll. Ja, wirklich.

Die Sicherheitsfirma Horizon3 hat Anfang Oktober aufgeschrieben, wie man das ausnutzt, gefunden hatten sie es mit Anthropics Modell Mythos. Einen Tag später liefen laut VulnCheck die ersten echten Angriffe auf Server in den USA und Japan (The Register via AI Weekly, DEV Community).

Was da eigentlich passiert ist

Kurz zur Technik. Math.random() ist in Node schnell, aber vorhersagbar. Wer genug Werte davon sieht, kann ausrechnen, welche Werte als nächstes kommen und welche vorher kamen. Bei HFS kam dazu, dass der Login ein paar dieser Zufallswerte nach außen gegeben hat, ohne dass man angemeldet sein musste. Ein paar Login-Versuche schicken, die Werte einsammeln, daraus den Schlüssel zurückrechnen, ein Admin-Cookie fälschen. Laut den Berichten reichen dafür ungefähr zwölf Anfragen (DEV Community). Als Admin kann man in HFS dann eigenen Code auf dem Server laufen lassen, und damit ist der Server halt weg.

Jeder Fehler für sich wäre wahrscheinlich nie aufgefallen. Schwacher Zufall irgendwo, ein Wert, der nach außen geht, das findet man halt in vielen Projekten. Und das meine ich ernst. Spannend ist, dass das Modell die zwei Stellen zusammengebracht hat. Genau das, was ein normaler Scanner nicht macht, weil er jede Stelle einzeln anguckt.

Der Fix war seit Juli da

Und das ist eigentlich der Teil, über den ich am meisten nachdenke. Die Lücke ist in der GitHub-Datenbank seit dem 13. Juli eingetragen, mit 9,3 von 10 Punkten, und die Version 3.2.1 behebt sie (GitHub Advisory). Wer seitdem einmal aktualisiert hat, war raus. Angegriffen wurden also Server, die knapp drei Monate lang niemand angefasst hat. Kennt man.

Ich hab ja gestern erst über die neuen Node-Versionen geschrieben und darüber, dass Wartung einen festen Termin braucht. Hier sieht man irgendwie ziemlich gut, was passiert, wenn der Termin fehlt. Solange nur in einer Datenbank steht, dass es eine Lücke gibt, passiert meistens gar nichts. Sobald aber jemand die Anleitung schreibt, ist das Zeitfenster ein Tag. Und mit Modellen, die solche Ketten selbst finden, wird es eher mehr Anleitungen geben als weniger. Ob das jetzt Fluch oder Segen ist, weiß ich ehrlich gesagt noch nicht, gefunden hat sie ja auch ein Modell, nur halt auf der Seite der Verteidiger.

Ich hab dann mal bei uns gesucht

Bevor ich anderen sowas erzähle, wollte ich mal wissen, wie es bei uns aussieht. Also einmal durch die eigenen Projekte gesucht, wo überall Math.random steht. Auf dieser Seite hier wird es tatsächlich für den Ladebalken benutzt, also genau für das, wofür es da ist. Die Tokens laufen über crypto.randomUUID(). In zwei anderen eigenen Apps laufen Login-Token und Codes über crypto.randomBytes. Passt.

In Caption & Cut hab ich eine Stelle gefunden, wo Math.random einen Namen für hochgeladene Dateien mitbaut. Die liegt hinter dem Login und ist kein Schlüssel, ich glaub also nicht, dass da was ist. Aber genau so eine Stelle guck ich mir jetzt trotzdem nochmal an, weil man bei HFS vermutlich auch gedacht hat, das ist nur ein Wert unter vielen.

Wie man das bei sich prüft

Wenn ihr eigene Software in Node oder im Browser laufen habt, egal ob selbst geschrieben oder von einer Agentur, sind es im Grundsatz drei Schritte:

  1. Im Code nach Math.random suchen und bei jeder Fundstelle fragen, ob daraus ein Passwort, ein Token, ein Link zum Zurücksetzen, ein Einladungscode oder ein Schlüssel entsteht. Wenn ja, gehört da crypto.randomBytes oder crypto.randomUUID hin.
  2. Aufschreiben, welche fertige Software ihr selbst betreibt, also Dateiserver, Wikis, kleine Tools auf dem eigenen Server, und welche Version davon läuft.
  3. Festlegen, wer die Sicherheitsmeldungen dazu liest und bis wann aktualisiert wird. Bei kritischen Lücken eher Tage als Monate.

Der erste Schritt dauert bei einem normalen Projekt vielleicht eine Viertelstunde. Geht schnell. Der dritte ist der, der bei den meisten fehlt. Und das ist ja eher eine Frage vom Ablauf als vom Code.

Wer nicht weiß, wo er da anfangen soll oder einfach mal einen zweiten Blick auf die eigene Software will, meldet sich gern. Mich würde aber auch interessieren, wie oft ihr bei euch überhaupt aktualisiert. Einmal im Monat, einmal im Jahr oder wenn halt was kaputt ist?

Falls du mit mir arbeiten willst

Lass uns reden – ich sage dir ehrlich, ob ich helfen kann.

Kontakt aufnehmen