KIberschutz: 14 Lücken in itflow behoben
Wir meldeten dem MSP-Werkzeug itflow 16 Funde. 14 sind mit Version 26.08 draußen, einen halten wir zurück, bis er behoben ist.
Transparenz vorweg: KIberschutz ist unser eigenes Projekt. Wir prüfen mit KI-Unterstützung Open-Source-Software auf Sicherheitslücken und melden die Funde verantwortungsvoll an die Maintainer. Nach logtide, Speakr und Mira ist das der vierte Fall, den wir hier aufschreiben, und mit Abstand der größte.
Eine Einordnung gleich zu Beginn: Wir haben am 26. Juli 16 Funde gemeldet. 15 davon stehen in diesem Artikel. Einen halten wir zurück, weil er noch nicht behoben ist. Der Maintainer hat ihn bewusst auf ein späteres Release gelegt, und bis er draußen ist, schreiben wir nichts darüber. Details dazu gibt es hier also erst später.
Was passiert ist
Das Projekt ist itflow, eine PSA-Software für IT-Dienstleister: Tickets, Rechnungen, Assets, Dokumentation, Domains, Zertifikate und ein Passwort-Tresor für Kundenzugänge, alles in einer selbst gehosteten PHP-Anwendung unter GPL-3.0. 965 Sterne auf GitHub, rund 89.000 Zeilen Code über 653 Dateien.
Das Nutzungsmuster macht diese Software besonders. Ein MSP betreibt itflow einmal und verwaltet darin die Zugänge vieler Kunden. Wer eine solche Instanz aufbricht, steht nicht vor den Daten eines Unternehmens, sondern vor denen aller betreuten. Genau deshalb schauen wir uns Werkzeuge dieser Bauart an: Der Schaden multipliziert sich hier über die Kundenliste.
Die Funde
Alle Meldungen liefen über private Security Advisories auf GitHub. Die Advisories sind noch nicht veröffentlicht, ein Link darauf wäre für euch aktuell nur eine Fehlerseite. Sobald das Projekt sie freigibt, tragen wir die Links hier nach. Bis dahin ist die Fix-Seite in den Release Notes zu v26.08 nachlesbar, die einen eigenen Security-Abschnitt haben.
| Fund | Schwere | Kurz erklärt |
|---|---|---|
| Credential-Freigabe ohne Rechteprüfung | hoch | Der Handler zum Teilen eines Eintrags prüfte nur die Helpdesk-Rolle, entschlüsselte aber Benutzername und Passwort und verschickte den Link per Mail. Eine Rolle ohne Zugriff aufs Passwort-Modul kam so an Klartext-Zugänge |
| Schwacher Zufall für TOTP-Secrets | hoch | Die Erzeugung der 2FA-Geheimnisse hing an einem schwachen Zufallsgenerator. Das Ergebnis war weit weniger unvorhersehbar, als ein zweiter Faktor sein muss |
| Zweiter Faktor nicht wirksam gebremst | hoch | Falsche 2FA-Codes zählten nicht auf die Loginsperre ein, und das akzeptierte Zeitfenster war zu breit. Wer das Passwort hatte, konnte den zweiten Faktor durchprobieren |
| Loginsperre per Anfragen-Schwall umgehbar | hoch | Die Sperre nach zu vielen Fehlversuchen wurde gelesen, bevor der Fehlversuch gebucht war. Viele parallele Anfragen sahen deshalb alle denselben Stand |
| Keine neue Session-ID beim Login | hoch | Die Sitzungskennung blieb über die Anmeldung hinweg gleich, was klassische Session-Fixation ermöglicht |
| Admin-Dialoge ohne Admin-Prüfung | mittel | Die Dialogfenster der Administration ließen sich direkt aufrufen. Darin standen die hinterlegten API-Schlüssel für Zahlungs- und KI-Anbieter, lesbar für jeden angemeldeten Nutzer |
| 2FA-Geheimnis im Gast-Link | mittel | Beim Teilen eines Zugangs landete das dauerhafte 2FA-Geheimnis im HTML der Gastseite, statt nur eines rotierenden Codes |
| Fremde Dokumente über die ID abrufbar | mittel | Die Dokumentansicht prüfte nicht, ob das Dokument zum eigenen Mandanten gehört |
| Abrufzähler geteilter Links umgehbar | mittel | Das Limit "nur einmal ansehen" wurde geprüft und erst danach hochgezählt. Parallele Aufrufe kamen alle durch |
| Zahlung doppelt verbuchbar | mittel | Im Gast-Zahlungsweg fehlte die Absicherung gegen Mehrfachverarbeitung derselben Zahlung. Der Maintainer stuft das als Korrektheitsfehler ein, nicht als Sicherheitslücke |
| SSRF beim Zertifikatsabruf | mittel | Der Abruf von TLS-Zertifikaten ließ sich auf interne Adressen richten. Siehe unten, hier gibt es bewusst keinen Fix |
| Ephemerer Freigabeschlüssel in der Mail-Warteschlange | niedrig | Der Schlüssel, mit dem ein geteilter Zugang entschlüsselt wird, blieb im Klartext in der Mail-Warteschlange liegen |
| Vorhersagbarer Dateiname für Uploads | niedrig | Hochgeladene Dateien bekamen einen ratbaren Namen und wurden ohne Anmeldung ausgeliefert |
| Gast-Sitzung ohne Cookie-Härtung | niedrig | Dem Cookie der Gastsitzung fehlten die Schutzflags |
| Zu kurzer Schlüssel für den Tresor | niedrig | Der Sitzungsschlüssel des Passwort-Tresors hatte weniger Entropie, als die verwendete Verschlüsselung eigentlich erwartet |
Die schwerste Gruppe dreht sich um Zugangsdaten und Anmeldung, und das ist bei einem Passwort-Tresor für Kundensysteme auch die schmerzhafteste Ecke. Der Fund zur Credential-Freigabe ist der beste Beleg dafür, warum Rechteprüfungen an jedem einzelnen Pfad sitzen müssen: Alle anderen Wege zu Kundenzugängen prüften das Passwort-Modul korrekt, nur dieser eine nicht.
Was der Maintainer daraus gemacht hat
Die Rückmeldung kam am Tag nach der Meldung, die inhaltliche Arbeit war im Wesentlichen nach zwei Tagen erledigt. Für neun Funde haben wir Patches beigesteuert, und zwar über den dafür vorgesehenen Weg: GitHub legt zu einem privaten Advisory auf Knopfdruck einen temporären privaten Fork an. Dort haben wir Fix-Branches gegen develop gebaut, statt öffentliche Pull Requests zu öffnen, die die Lücken vorzeitig sichtbar gemacht hätten.
Ein Fund bekommt bewusst keinen Fix. Der Abruf von TLS-Zertifikaten lässt sich auf interne Adressen richten, was in der Theorie ein Scan des internen Netzes ist. Der Maintainer stuft das als gewolltes Verhalten ein, weil itflow damit auch Zertifikate im eigenen Netz prüfen können soll. Das ist eine vertretbare Abwägung, die wir hier trotzdem benennen: Wer itflow betreibt, sollte wissen, dass ein angemeldeter Mitarbeiter diese Funktion auf interne Adressen richten kann.
Auffällig ist außerdem, was im Release sonst noch steckt. v26.08 ist kein reines Fix-Release, sondern bringt eine überarbeitete Cron-Struktur, verschlüsselte Backups, SLAs für Tickets und ein neues Rechtemodell für API-Schlüssel mit. Die Sicherheitsarbeit lief also parallel zu einer großen Funktionsrunde, nicht statt ihr.
Warum der Fall bei uns einen Namen trägt
Vor zwei Tagen haben wir hier die Statusseite von KIberschutz vorgestellt und die Regeln beschrieben, nach denen ein Projekt dort namentlich erscheint. Der Hauptweg dorthin: erst dann, wenn alle Funde behoben und ausgeliefert sind. Genau an diesem Fall ist die Regel gescheitert, und wir haben sie geändert.
Seit heute hängt die Sichtbarkeit am einzelnen Fund statt am ganzen Fall. Sobald ein Fix in einer echten Version beim Nutzer angekommen ist, zeigen wir diesen Fund, und das Projekt bekommt seinen Namen. Was noch offen ist, bleibt vollständig draußen, auch aus den Zahlen.
Wenn ihr itflow selbst betreibt
Aktualisiert auf v26.08. Drei Dinge, die dabei zählen:
- Lest die Upgrade-Anleitung vor dem Update. Dieses Release ändert die Datenbankstruktur, ersetzt die komplette Cron-Einrichtung und braucht einen Schritt auf der Kommandozeile. In der falschen Reihenfolge ausgeführt, steht die Instanz. Die Schritte stehen oben in den Release Notes.
- Wechselt eure API-Schlüssel. Wegen der offenen Admin-Dialoge konnte jeder angemeldete Nutzer die hinterlegten Schlüssel für Zahlungs- und KI-Anbieter lesen, ohne dass das irgendwo protokolliert wurde. Es lässt sich also nicht nachvollziehen, wer sie gesehen hat. Das Release weist selbst darauf hin. Alle bestehenden API-Schlüssel von itflow werden beim Update ohnehin gelöscht und müssen neu erzeugt werden.
- Prüft geteilte Zugänge. Wo Zugänge über die Gast-Freigabe geteilt wurden, waren das 2FA-Geheimnis und der Entschlüsselungsschlüssel breiter sichtbar als vorgesehen. Ein Wechsel der betroffenen Kundenzugänge ist der sichere Weg.
Warum das zählt
Vierter Fall, und das Muster aus den ersten dreien hält auch bei deutlich größerem Umfang. 16 Funde in einer gewachsenen PHP-Anwendung mit 89.000 Zeilen, davon 14 behoben und ausgeliefert, neun davon mit Patches von uns. Ein Maintainer, der am Tag nach der Meldung antwortet und die Sicherheitsarbeit neben einer großen Funktionsrunde unterbringt.
Der zurückgehaltene Fund ist der Grund, warum dieser Artikel 15 statt 16 Lücken beschreibt. Das bleibt so, bis ein Fix ausgeliefert ist. Nebenbei hat uns der Fall eine Regel auf der eigenen Statusseite gekostet, die zu grob war.
Danke an johnnyq für die schnelle Rückmeldung und die saubere Einarbeitung.