← Zurück zum Blog
9 novembre 2026 · 14 min Lesezeit

Semaphore UI und HFS: zwei Autorisierungsfehler, die wir gemeldet haben

GHSA-ffp6-w57q-758q und GHSA-c3w7-ff56-j345: In Semaphore UI konnte ein Manager den Vault eines anderen Projekts ins eigene verschieben, in HFS konnte ein anonymer Besucher die gerade hochgeladene Datei eines anderen ersetzen. Was wir gefunden haben und welche Versionen Sie installieren sollten.

IT-SicherheitSemaphore UIHFSAnsibleWebDAVOffenlegung von Schwachstellen
Schema der beiden Schwachstellen: In Semaphore UI verschiebt ein Manager von Projekt A den Vault von Projekt B; in HFS ersetzt ein zweiter anonymer Besucher die gerade hochgeladene Datei eines anderen

Am 9. November 2026 haben innerhalb einer Stunde zwei sehr unterschiedliche Open-Source-Projekte ein Sicherheits-Advisory mit demselben Namen in den Credits veröffentlicht. Das erste ist Semaphore UI, die Weboberfläche, mit der viele Teams Ansible und Terraform auf ihren Servern ausführen. Das zweite ist HFS, der Dateiserver, mit dem man seit 2003 einen Ordner auf dem eigenen Computer über einen einfachen Browser freigeben kann. In Semaphore konnte ein Benutzer eines Projekts einem anderen Projekt die Vault-Konfiguration eines Templates wegnehmen. In HFS konnte ein anonymer Besucher die Datei ersetzen, die ein anderer anonymer Besucher gerade hochgeladen hatte, in einem Ordner, in dem Löschen verboten war.

Es geht um die Advisories GHSA-ffp6-w57q-758q, behoben in Semaphore UI 2.19.20, und GHSA-c3w7-ff56-j345, behoben in HFS 3.4.1. Wir haben sie gemeldet: Beide Funde stammen von Liam Giannini (Liam-G auf GitHub), ethischer Hacker und Mitgründer von Webcracy. Wir danken den Maintainern von Semaphore und Massimo Melina, dem Autor von HFS, die Advisories und korrigierte Versionen am selben Tag veröffentlicht haben.

Die beiden Fehler wirken grundverschieden, haben aber dieselbe Wurzel. In beiden Fällen prüfte das Programm eine Identität, nur eben die falsche.

Webcracy und IT-Sicherheit

Neben Websites und Anwendungen beschäftigt sich Webcracy mit allen Bereichen der IT-Sicherheit: Wir schützen Netzwerke und Server, überwachen sie mit unserem SOC Tag und Nacht, greifen bei Vorfällen ein, machen Audits, Beratung und Härtung von Systemen und stellen die Abwehr mit Penetrationstests und Code-Reviews auf die Probe. Die Forschung an der Open-Source-Software, die wir selbst und unsere Kunden einsetzen, ist ein Teil dieser Arbeit. Liam sucht Schwachstellen mit den Methoden eines Angreifers, aber damit sie geschlossen werden: Er meldet sie vertraulich an die Maintainer und macht sie erst öffentlich, wenn eine Korrektur verfügbar ist. Es ist dieselbe verantwortungsvolle Offenlegung wie bei ProjectSend, exarch und FreeScout.

Semaphore UI: der Vault, der von einem Projekt ins andere wanderte

Warum Semaphore UI wichtig ist

Semaphore UI ist eine Weboberfläche und API, mit der man Ansible, Terraform, OpenTofu, Terragrunt, Pulumi und PowerShell ausführen kann, ohne über die Kommandozeile zu gehen. Das Projekt existiert seit 2014, damals noch unter dem Namen Ansible Semaphore, ist in Go geschrieben und steht unter der MIT-Lizenz. Auf GitHub hat es über 14'400 Sterne, mehr als 1'300 Forks und über 180 Mitwirkende; das offizielle Docker-Image semaphoreui/semaphore wurde mehr als 8,6 Millionen Mal heruntergeladen, dazu kommen rund 600'000 Downloads des alten Images ansiblesemaphore/semaphore. Die Website des Projekts spricht von über 100'000 Installationen: Diese Zahl stammt vom Hersteller, die Grössenordnung passt aber zu allem anderen. Neben der Open-Source-Version gibt es kostenpflichtige Pro- und Enterprise-Editionen.

In der Ansible-Welt ist es die leichtgewichtige Alternative zu AWX und zur Ansible Automation Platform von Red Hat: ein einzelnes Binary, das mit einer SQLite-Datenbank starten kann und keinen Kubernetes-Cluster wie AWX braucht. Deshalb ist es eine häufige Wahl für alle, die eine Oberfläche für Ansible wollen, ohne noch eine weitere Infrastruktur aufzubauen.

Und hier wiegt ein Autorisierungsfehler schwerer als anderswo. Ein solches Werkzeug enthält die SSH-Schlüssel, die Cloud-Zugangsdaten, die Passwörter, mit denen verschlüsselte Geheimnisse entsperrt werden: Von hier aus gehen die Befehle an die gesamte Infrastruktur. Deshalb ist es in Projekte aufgeteilt, und oft bedient dieselbe Installation mehrere Teams oder mehrere Kunden. Die Grenze zwischen zwei Projekten ist in der Praxis die Grenze dafür, wer was anfassen darf.

Was Template-Vaults sind

In Semaphore beschreibt ein Template eine auszuführende Aufgabe: welches Playbook, auf welchem Inventar, mit welchen Variablen. Viele Playbooks enthalten Geheimnisse, die mit Ansible Vault verschlüsselt sind, und zum Entschlüsseln braucht es ein Passwort. Das Template legt mit einer oder mehreren Vault-Verknüpfungen fest, woher es kommt: aus einem im Projekt gespeicherten Schlüssel oder aus einem Skript, das es von einem externen System holt. In der Datenbank ist jede Verknüpfung eine Zeile der Tabelle project__template_vault, mit eigener numerischer ID sowie dem Projekt und Template, zu dem sie gehört.

Wo die Prüfung fehlte

Ein Template wird mit POST /api/project/{project_id}/templates erstellt. Die Middleware prüft korrekt, dass der Benutzer Mitglied des Projekts in der URL ist und dessen Ressourcen verwalten darf, was die Rolle Manager erlaubt. Das neue Template wird diesem Projekt zugeordnet, aber die Liste vaults gelangt genau so in die Datenbank, wie der Client sie geschickt hat.

Der Fehler lag in der Funktion UpdateTemplateVaults. Für jeden Eintrag mit einer ID ungleich null nahm sie an, es handle sich um eine bestehende Verknüpfung, die aktualisiert werden soll, und führte aus:

UPDATE project__template_vault
SET project_id=?, template_id=?, vault_key_id=?, name=?, type=?, script=?
WHERE id=?

Die Zeile wurde allein über id ausgewählt, ohne zu prüfen, zu welchem Projekt sie gehörte, und das Update schrieb ausgerechnet project_id und template_id neu und übertrug sie auf das neue Template des Angreifers. Das spätere Löschen überzähliger Verknüpfungen war auf das Projekt beschränkt, kam aber erst, als die Zeile schon verschoben war.

Ein Angreifer musste also nur im eigenen Projekt ein Template erstellen und in die Liste vaults die ID einer Verknüpfung des Opferprojekts setzen. Mit dem Typ script wird das Schlüsselfeld geleert, weitere Informationen über das fremde Projekt waren also nicht nötig. Und die IDs sind Zahlen, welche die Datenbank fortlaufend vergibt, keine Geheimnisse. Die Prüfung galt dem Projekt in der URL, das veränderte Objekt wurde aber über eine Zahl im Request-Body ausgewählt: Der CWE-Katalog nennt das CWE-639, Umgehung der Autorisierung über einen vom Benutzer kontrollierten Schlüssel, und CWE-863, fehlerhafte Autorisierung.

Wie schwerwiegend es ist

Nach der Anfrage hat das Template des Opferprojekts seine Vault-Verknüpfung nicht mehr, das Template des Angreifers schon. Die wahrscheinlichste Folge: Ausführungen, die Geheimnisse entschlüsseln müssen, schlagen fehl, bis jemand die Konfiguration neu anlegt. In unserem Test haben wir das nicht gemessen: Es ist eine plausible Folge, keine nachgewiesene.

Ebenso genau sagen wir, was wir nicht gefunden haben: kein Auslesen von Geheimnissen, keine Verwendung des Schlüssels des Opfers, keine Codeausführung. Ausserdem braucht der Angreifer die Rolle Manager oder gleichwertige Rechte in mindestens einem Projekt. Deshalb ist der Schweregrad mittel. Aber in einem Werkzeug, das die Infrastruktur orchestriert, heisst «mittel» trotzdem: Ein Benutzer konnte ein Projekt verändern, in dem er keinerlei Rolle hatte, und wer die Projekte anderer Teams oder Kunden betreut, hätte es nicht kommen sehen.

Wie wir es überprüft haben

Das Problem ist beim Lesen des Codes von Semaphore UI 2.19.18 (Commit b621d14) aufgefallen, als wir der Liste vaults vom Router bis zur SQL-Abfrage gefolgt sind. Zur Bestätigung hat Liam einen Regressionstest in Go geschrieben, der die In-Memory-SQLite-Datenbank der Release und die Originalkomponenten verwendet: Projekt-Middleware, Berechtigungsprüfung, Template-Erstellung und SQL-Schicht. Der Test legt zwei Projekte an, A und B, macht den Benutzer nur in A zum Manager, erstellt in B ein Template mit einem Vault und verlangt dann, in A ein Template mit der ID der Verknüpfung aus B zu erstellen. Die API antwortete mit 201, das Template in B ging von einer Verknüpfung auf null zurück, und das neue Template in A enthielt die ursprüngliche aus B.

Dieselbe Abfrage steht mindestens seit Version 2.11 im Code von Semaphore. Das Advisory nennt nur die Version, die wir überprüft haben, 2.19.18, und legt nicht fest, welche älteren Versionen auf dieselbe Weise ausnutzbar sind. Man sollte davon ausgehen, dass sie es sind.

Die Korrektur in 2.19.20

Version 2.19.20 enthält die Korrektur, im Commit 9445ee9 aus Pull Request #4414. Das Update rührt project_id und template_id nicht mehr an und findet die Zeile nur, wenn sie wirklich zum autorisierten Projekt und Template gehört:

UPDATE project__template_vault
SET vault_key_id=?, name=?, type=?, script=?
WHERE id=? AND project_id=? AND template_id=?

Eine ID aus einem anderen Projekt hat keine Wirkung mehr. Die Maintainer haben ausserdem einen Test hinzugefügt, TestManagerCannotMoveForeignProjectVault, der das Szenario des Advisorys nachstellt. In unserer Meldung hatten wir zusätzlich vorgeschlagen, die Anfrage abzulehnen, wenn das Update keine Zeile trifft, und Template und Verknüpfungen in einer einzigen Transaktion anzulegen: Die veröffentlichte Korrektur schliesst den Angriffsweg, die weiteren Massnahmen bleiben eine Entscheidung der Maintainer.

Was tun, wenn Sie Semaphore UI einsetzen

Aktualisieren Sie mindestens auf 2.19.20, besser noch auf 2.19.21, die wenige Minuten später erschienen ist und laut den Release Notes ein weiteres Problem behebt: Ein Benutzer konnte sein eigenes Passwort über die API ändern, ohne das aktuelle zu kennen. Legen Sie bei Docker eine explizite Version fest statt latest.

Prüfen Sie nach dem Update, ob die Templates, die Ansible Vault verwenden, ihre Verknüpfungen noch haben: Wenn eines seinen Vault ohne erkennbaren Grund verloren hat, kennen Sie jetzt eine mögliche Ursache. Und prüfen Sie, wer die Rolle Manager hat, und in welchen Projekten. Wenn die Trennung zwischen zwei Benutzergruppen wirklich kritisch ist, etwa zwischen verschiedenen Kunden eines Dienstleisters, sind die Projekte einer einzigen Installation eine nützliche, aber keine absolute Grenze: Getrennte Instanzen mit getrennten Datenbanken begrenzen den Schaden des nächsten Autorisierungsfehlers.

HFS: die frisch hochgeladene Datei, die ein anderer Anonymer ersetzen konnte

Warum HFS wichtig ist

HFS, HTTP File Server, ist eines jener Programme, denen fast jeder, der seit einigen Jahren in der Informatik arbeitet, schon begegnet ist. Massimo Melina, online als rejetto bekannt, entwickelt es seit Anfang der 2000er-Jahre: Man startet es auf dem eigenen Computer, wählt die freizugebenden Ordner, und jeder mit der Adresse kann per Browser Dateien herunter- oder hochladen, ohne Cloud-Dienst dazwischen. Auf SourceForge zählt das Projekt seit 2003 über 970'000 Downloads, die von der Website des Autors nicht mitgerechnet. HFS 3, in TypeScript auf Node.js neu geschrieben und unter der GPL-3.0 veröffentlicht, läuft auf Windows, Linux, macOS, FreeBSD und Android. Auf GitHub hat es fast 4'000 Sterne und über 370 Forks; die Release-Pakete wurden mehr als 500'000 Mal heruntergeladen, das Docker-Image rejetto/hfs über 116'000 Mal und das npm-Paket rund 44'000 Mal im letzten Jahr.

Es eignet sich, um Dateien im lokalen Netz weiterzugeben oder Dokumente von Kunden und Mitarbeitenden entgegenzunehmen: Umgebungen, in denen ein Ordner mit anonymem Upload, aber Schutz vor dem Löschen, eine ganz normale Konfiguration ist. Jeder kann eine Datei abgeben, niemand kann eine entfernen.

Die zehn Sekunden für WebDAV

Seit Version 3.1.0, erschienen im April 2026, unterstützt HFS WebDAV, das Protokoll, mit dem man einen freigegebenen Ordner als Netzlaufwerk im Windows-Explorer oder im Finder des Mac einbinden kann. Manche WebDAV-Clients verhalten sich eigenwillig: Der Finder etwa legt zuerst eine leere Datei an und überschreibt sie sofort mit dem eigentlichen Inhalt. Eine Datei zu überschreiben erfordert aber die Berechtigung zum Löschen, und ein Ordner «nur Upload» gewährt sie nicht.

Um diese Clients nicht zu blockieren, gibt HFS demjenigen, der gerade mit einem erkannten WebDAV-Client eine Datei hochgeladen hat, zehn Sekunden, um sie zu ersetzen, auch ohne Löschberechtigung. Ein vernünftiger Kompromiss. Die Frage ist, wie HFS entschied, wer «derjenige, der gerade hochgeladen hat» war.

Alle Anonymen haben denselben Namen

Die vorübergehende Berechtigung wurde unter einem Schlüssel aus zwei Teilen gespeichert: dem Pfad der Datei und dem Namen des Benutzers. Für registrierte Benutzer funktioniert das, und es gab sogar einen automatischen Test, der prüfte, dass zwei verschiedene Konten die Berechtigung des jeweils anderen nicht nutzen konnten. Aber für jemanden, der nicht angemeldet ist, liefert HFS als Namen eine leere Zeichenkette. Alle anonymen Besucher hatten denselben Namen und damit denselben Schlüssel.

Ein zweiter anonymer Besucher konnte daher, ohne die Cookies oder Zugangsdaten des ersten, innerhalb von zehn Sekunden eine PUT-Anfrage an denselben Pfad senden, mit einem User-Agent, der das Wort WebDAV enthielt. HFS fand die Berechtigung, löschte die vorhandene Datei, noch bevor der neue Upload verarbeitet wurde, und umging sowohl die Prüfung can_delete als auch den Schutz, der anonyme Uploads an die Sitzung bindet, die sie erstellt hat. Gelang der neue Upload, war die Datei ersetzt; schlug er fehl oder wurde er abgebrochen, war das Original trotzdem gelöscht. Die standardmässig aktive Option force_webdav_login blockierte diese Anfrage nicht, weil ein einfaches PUT ohne WebDAV-spezifische Header nicht als WebDAV-Authentifizierungsanfrage behandelt wurde. Auch hier spricht der Katalog von CWE-863, fehlerhafte Autorisierung.

Wie schwerwiegend es ist

Die Bedingungen sind eng. Es braucht einen Ordner mit anonymem Upload und Löschverbot, eine gerade von einem WebDAV-Client hochgeladene Datei, die Kenntnis ihres Pfads und eine zweite Anfrage innerhalb von zehn Sekunden. Ältere Dateien sind nicht erreichbar. Der Schweregrad ist mittel.

Innerhalb dieses Fensters ist die Wirkung aber konkret: Eine gerade veröffentlichte Datei, vielleicht schon per Adresse mit anderen geteilt, konnte von irgendjemandem durch anderen Inhalt ersetzt werden, unter derselben Adresse. In einem Abgabeordner heisst das: Das empfangene Dokument ist vielleicht nicht das, welches der Absender geschickt hat.

Wie wir es überprüft haben

Liam hat den Ablauf im Code von HFS 3.3.4 (Commit bb6f718) nachverfolgt und bestätigt, dass derselbe Code noch im Hauptzweig vorhanden war. Dann hat er den Server gebaut und in einem Docker-Container ohne Netzwerkzugang gestartet, mit einem Ordner uploads, der Uploads erlaubt und Löschen verbietet. Eine erste anonyme Sitzung lud eine Datei mit dem Inhalt first hoch, mit dem User-Agent des WebDAV-Clients von Windows. Eine zweite Sitzung ohne Cookies versuchte, sie zu löschen, und HFS antwortete korrekt mit 403. Dieselbe zweite Sitzung schickte dann ein PUT an denselben Pfad mit dem Inhalt second: HFS antwortete mit 200, und die Datei unter der ursprünglichen Adresse enthielt second.

Beide Anfragen kamen von derselben IP-Adresse, aber der Schlüssel enthält weder die Sitzung noch die IP: Der Code zeigt, dass das Ergebnis von verschiedenen Adressen aus identisch wäre, auch wenn wir diesen Fall nicht separat getestet haben. Das Advisory nennt alle Versionen von 3.1.0 bis 3.4.0 als betroffen.

Die Korrektur in 3.4.1

Version 3.4.1, erschienen am 9. November, nennt in den Release Notes eine einzige Änderung, im Commit 9a33df2: Die vorübergehende Berechtigung ist jetzt an den Benutzernamen gebunden oder, bei anonymen Besuchern, an die Kennung ihrer Sitzung. Gibt es keines von beiden, wird keine Berechtigung erteilt. Genau diese Lösung hatten wir vorgeschlagen. Der neue automatische Test prüft beide Seiten: Eine andere anonyme Sitzung erhält 403, während der Uploader die Datei weiterhin überschreiben kann, wie der Finder es tut.

Was tun, wenn Sie HFS einsetzen

Aktualisieren Sie auf 3.4.1 oder neuer. HFS hat eine automatische Update-Funktion, die auch beim Betrieb als Dienst verfügbar ist, daher geht das meist schnell. Wenn Sie aus irgendeinem Grund nicht sofort aktualisieren können und Ordner mit anonymem Upload haben, erwägen Sie, für Uploads ein Konto vorauszusetzen, zumindest bis die Korrektur installiert ist.

Allgemeiner gilt: Ein Ordner mit anonymem Upload ist per Definition eine offene Tür. In vielen Fällen ist das sinnvoll, aber er eignet sich besser zum Empfangen von Dateien als zum Veröffentlichen für andere, und sein Inhalt sollte regelmässig kontrolliert werden.

Zweimal derselbe Fehler

Semaphore prüfte, ob der Benutzer im Projekt aus der URL arbeiten durfte, und veränderte dann ein Objekt, das über eine Zahl in der Anfrage ausgewählt wurde. HFS prüfte, ob die Datei vom selben Benutzer hochgeladen worden war, verwendete aber einen Namen, der für alle anonymen Besucher identisch war. In beiden Fällen war die Prüfung da, sorgfältig geschrieben, und in einem Fall sogar durch einen Test abgedeckt. Es fehlte die richtige Frage: Ist die Identität, die ich prüfe, wirklich die der Person und des Objekts, auf die ich gleich einwirke?

Solche Fehler fallen bei der normalen Nutzung einer Anwendung nicht auf. Sie fallen auf, wenn man einen Wert von der Anfrage bis zu dem Punkt verfolgt, an dem er verwendet wird, und sich jedes Mal fragt: «Wer hat diesen Wert bestimmt?» Das ist ein Teil unserer Arbeit.

Warum wir Open-Source-Software untersuchen

Werkzeuge wie Semaphore und HFS sind der Grund, warum ein kleines Team Dutzende Server verwalten oder Dateien austauschen kann, ohne von einem Cloud-Dienst abhängig zu sein: Open Source, kostenlos, einfach zu installieren. Doch je verbreiteter eine Anwendung ist, desto wichtiger sind ihre internen Prüfungen. Den Code der Projekte zu lesen, die wir nutzen und empfehlen, und unsere Funde zu melden, ist unsere Art, diesen Projekten etwas zurückzugeben und zu wissen, was wir bei unseren Kunden installieren.

Wenn Sie Automatisierungswerkzeuge, Dateiserver oder Anwendungen mit mehreren Benutzern und Rollen einsetzen und wissen möchten, ob die Berechtigungen wirklich halten, sprechen wir gern darüber. Unsere Arbeit in der IT-Sicherheit umfasst Schutz und Überwachung von Netzwerken, Incident Response, Audits, Härtung und Penetrationstests, und sie beginnt immer hier: Code und Konfiguration lesen, verstehen, wo eine Prüfung fehlt, und Ihnen genau sagen, was wir überprüft haben und was nicht.

Sprechen wir über die Sicherheit Ihres Unternehmens

HABEN SIE EIN PROJEKT?

Lassen Sie uns besprechen, wie wir Ihrem Unternehmen mit massgeschneiderten digitalen Lösungen helfen können.

KONTAKT