Die Wordlist kannte Ihr Home-Verzeichnis bereits
F5 Labs zählte in einem Monat 807 Angriffe und 32.000 Ereignisse gegen exponierte Vite-Entwicklungsserver, mit einem Query-String-Trick, der an Vites eigener Deny-List vorbeiläuft. Die Scanner suchen nicht Ihre Anwendung. Sie fragen nach /home/ubuntu/.aws/credentials mit absolutem Pfad, und nach /proc/self/environ, und nach terraform.tfstate. In einem Workspace von Bromure Agentic Coding zeigt dieser Port auf einen privaten Switch, und die Datei, die die Wordlist will, enthält keinen Schlüssel.
Dieser Angreifer schickt Ihnen kein Paket und kein Archiv. Ihr eigener Entwicklungsserver lauscht, und ein Fremder fragt ihn nach Dateien mit Namen. Welche Maschine antwortet, entscheidet darüber, was er bekommt.
Sie sagen dem Agenten, er soll das Frontend zum Laufen bringen, damit Sie es
ansehen können. Er tippt npm run dev, bindet den Port, lädt die Seite, und Sie
gehen zurück zum Diff. Irgendwo in dieser Schleife, in einer
docker-compose.yml oder in einem --host-Flag, das Sie vor Wochen ergänzt
haben, damit die Vorschau vom Handy aus erreichbar ist, hat sich der Server an
alle Interfaces gebunden statt an Loopback. Zwölf Minuten später fragt etwas, das
sich Googlebot nennt, Ihren Entwicklungsserver nach /@fs/../.env?raw?? und
bekommt ein HTTP 200.
F5 Labs veröffentlichte die Zahlen am 11. September. Über einen einzigen Monat Sensordaten hinweg, den August 2026, verzeichneten ihre Honeypots 807 nach Sitzung gruppierte Angriffe und rund 32.000 Rohereignisse gegen exponierte Vite-Entwicklungsserver, gegenüber einer Grundlinie von 1.732 Ereignissen in den drei Monaten davor. Das ist das Achtzehnfache des Verkehrs, von Monat zu Monat, wegen eines einzigen Fehlers. BleepingComputer berichtete am 14. September darüber.
Ein Query-String, der an der Deny-List vorbeigeht
Vite liefert Dateien aus dem Dateisystem des Hosts über eine interne Route namens
/@fs/ aus, über die der Entwicklungsserver Ihrem Editor ein Modul reicht, das
außerhalb des Projektstamms liegt. Weil diese Route überallhin reichen kann,
liefert Vite eine Deny-List mit, server.fs.deny, um die offensichtlichen Ziele
zu blockieren: .env-Dateien, Zertifikate, privaten Quellcode.
CVE-2026-39364, veröffentlicht am 7. April, lässt einen Angreifer diese Deny-List überspringen, indem er die Anfrage mit einem Query-String schmückt. F5 beschreibt den Mechanismus:
Der Server verarbeitet die Anfrage, normalisiert den Pfad und entfernt oder missdeutet den Query-String während der Zugriffsprüfung, sodass die Prüfung server.fs.deny nicht ausgelöst wird.
Der Server erzwingt die Deny-List-Filterung nicht und liefert die Zieldatei mit einer HTTP-200-Antwort aus.
Der Fehler betrifft Vite 7.1.0 bis 7.3.2 sowie 8.x vor 8.0.5. F5 fing diese
Anfrageformen in freier Wildbahn ab, jede kurz genug für eine Zeile:
GET /@fs/.env?raw??, GET /@fs/../.env?raw??,
GET /@fs/..%252f..%252f..%252f..%252froot/.env?raw?? und
GET /@fs/..%252f..%252f..%252f..%252fproc/self/environ?raw??. Andere Varianten
im selben Werkzeugkasten nutzen ?import&raw, ?import&url&inline,
?inline&import und ?raw?import.
Diese Parametertricks tragen eigene CVE-Nummern: CVE-2025-30208, CVE-2025-31125
und CVE-2024-45811, drei ältere @fs-Umgehungen, die noch immer in denselben
Scannern geladen sind. Wer die Scan-Flotte betreibt, hat nicht für einen neuen
Fehler umgerüstet. Er hat einer Datei, die er schon hatte, eine weitere Zeile
angehängt.
Die Wordlist ist eine Karte der Maschine einer Entwicklerin
Lesen Sie, wonach die Scanner fragen, und achten Sie darauf, wie wenig davon Ihre Anwendung betrifft.
Sie fragen nach .env, .env.local, .env.production, .env.development und
.env.staging. Sie fragen nach terraform.tfstate, terraform.tfvars,
.terraform/terraform.tfstate, serverless.yml und
.serverless/serverless-state.json. Sie fragen nach .azure/credentials und
.azure/accessTokens.json. Sie fragen nach /etc/passwd, /proc/1/environ,
/proc/self/cwd/.env und /proc/self/environ. Dieser letzte Pfad enthält den
Umgebungsblock des Entwicklungsserver-Prozesses selbst, dort wo ein von Ihrer
Shell exportierter API_KEY landet.
Und dann fragen sie nach AWS-Zugangsdaten, indem sie die Liste der Home-Verzeichnisse durchgehen, unter denen der Prozess einer Entwicklerin laufen könnte:
/root/.aws/credentials, /home/ec2-user/.aws/credentials,
/home/ubuntu/.aws/credentials, /home/node/.aws/credentials,
/home/www-data/.aws/credentials, /home/admin/.aws/credentials,
/home/debian/.aws/credentials, /var/www/.aws/credentials,
/usr/src/app/.aws/credentials, /app/.aws/credentials. Dann .aws/config,
.aws/credentials.backup, .aws/credentials.bak, .aws/sso/cache/,
rootkey.csv, aws-exports.js und amplifyconfiguration.json.
Diese Pfade inventarisieren eine Entwicklermaschine, aufgezählt nach Benutzernamen, und Vite ist nur die Tür. Der Fehler ist nebensächlich; drei ältere Fehler in derselben Route fahren in denselben Anfragen mit. Die Betreiber wetten darauf, dass ein Prozess, der auf einer routbaren Adresse lauscht, unter einem Benutzer läuft, in dessen Home-Verzeichnis echte Schlüssel liegen.
Der Verkehr ist so gekleidet, dass er einen flüchtigen Blick in die Logs
übersteht. F5 verzeichnete gefälschte User-Agent-Header im Wechsel zwischen
Googlebot/2.1, ClaudeBot/1.0, GPTBot/1.4, PerplexityBot/1.0,
OAI-SearchBot/1.3 und Amazonbot/0.1, dazu gefälschte Werte für
X-Forwarded-For und X-Real-IP, um an IP-Allow-Lists vorbeizukommen. Die
Quellen liegen in den Bereichen 34.x und 35.x der Google Cloud über mehrere
Regionen verteilt, angeführt von den Vereinigten Staaten mit 17.297 Ereignissen,
dann Belgien mit 4.407 und den Niederlanden mit 4.011. In diesem Monat ist eine
Zeile in Ihrem Zugriffslog, die von sich behauptet, ein KI-Crawler zu sein, ein
schwacher Beleg dafür, dass ein Crawler sie geschickt hat.
Zwei von F5s Empfehlungen sind Architekturfragen
F5 schließt mit fünf Ratschlägen. Drei sind gewöhnlich und richtig: auf 7.3.2
oder 8.0.5 aktualisieren, /@fs/ am Rand filtern, Crawler per Reverse DNS prüfen
statt dem Header zu glauben. Die anderen beiden beschreiben eine Haltung, die man
halten muss, und keine Aufgabe, die man abschließt.
Stellen Sie sicher, dass Entwicklungsserver nicht an externe Interfaces binden. Prüfen Sie Docker-compose-Konfigurationen, Kubernetes-Ingress-Regeln und Cloud-Sicherheitsgruppen.
Rotieren Sie exponierte Geheimnisse: Wenn ein ungepatchter Vite-Entwicklungsserver im August 2026 aus externen Netzen erreichbar war, behandeln Sie lokale .env-Variablen, AWS-Zugangsdaten, Azure-Access-Token und Terraform-State-Dateien als potenziell kompromittiert.
Die erste verlangt, dass Sie ein Versprechen über jeden Port halten, in jeder
Compose-Datei, über jeden Branch hinweg, solange das Projekt lebt, in einem
Moment, in dem das, was npm run dev tippt, oft ein Agent ist und nicht Sie. Die
zweite fragt, was Sie danach tun, und antwortet: rotieren Sie, was die Maschine
sehen konnte.
Beides wird leichter, wenn der Port anderswo aufgeht und die Dateien, die die Wordlist nennt, nichts enthalten, das eine Rotation wert wäre.
Wo ein Bromure-Workspace den Port hinlegt
Bromure Agentic Coding führt Coding-Agenten in einer hardwarevirtualisierten Linux-VM auf Ihrem Mac aus, mit den Sicherheitskontrollen auf der Host-Seite dieser Grenze. Zwei davon antworten auf diese Kampagne.
Der Entwicklungsserver bindet innerhalb eines privaten Switch. Im
Standard-NAT-Modus hängt jede Workspace-VM an einem prozessweiten
Software-L2-Switch, gemultiplext auf eine einzige vmnet-Schnittstelle, in einem
privaten Subnetz. Dieses Subnetz ist 192.168.64.0/24, sofern Ihr eigenes LAN es
nicht schon benutzt, Bromure betreibt darauf einen eigenen DHCP-Server, und jeder
Workspace behält eine deterministische MAC und ein stabiles Lease. Das Handbuch
nennt die Konsequenz: Ihr Mac erreicht die VMs, Ihr physisches LAN sieht sie
nicht, und eingehende Verbindungen von anderswoher sind unmöglich, solange Sie
nicht selbst einen Dienst veröffentlichen. Ein Agent, der in dieser VM an
0.0.0.0 bindet, hat an jede Schnittstelle gebunden, die ihm gehört, und jede
davon zeigt auf einen Switch, der auf Ihrem Laptop beginnt und endet. Sie haben
keine Sicherheitsgruppe zu prüfen, weil Sie keine Route hinein zu sichern haben.
Sie sehen trotzdem, was lauscht, und es ist eine Liste, kein Audit. Das
Workspace-Dashboard trägt eine Listening-Ports-Karte, die jeden von außen
erreichbaren Socket im Gast als Endpunkt <VM-IP>:<Port> mit Kopieren per Klick
zeigt. Das macht aus F5s Empfehlung Nr. 2 eine Karte, auf die Sie kurz blicken,
alle anderthalb Sekunden aus dem Gast aufgefrischt, statt eines Audits, das Sie
terminieren. Wenn Sie doch einmal wollen, dass die Welt eine Vorschau sieht,
bekommt ein wahrscheinlich-HTTP-Dienst einen Globus-Knopf, der genau diesen
einen Dienst über einen Cloudflare Quick Tunnel veröffentlicht, hinter einem
einmaligen Einwilligungsdialog. Sie geben einen Dienst frei, indem Sie ihn
anklicken, Dienst für Dienst, auf dem Host, statt ein Flag in einer
Compose-Datei am Leben zu lassen.
Der Grund, aus dem Sie ursprünglich zu --host gegriffen haben, bleibt Ihnen
erhalten. Der wegwerfbare Chromium-Sidecar teilt sich dasselbe L2-Segment mit der
Workspace-VM, sodass der eingebettete Browser den Entwicklungsserver des Agenten
unter der Adresse der VM lädt. Nicht unter localhost, denn der Browser läuft
auf einer eigenen Maschine.
Wenn andere Maschinen die VM wirklich erreichen müssen, hängt der Bridged-Modus sie an Ihr physisches LAN. Das stellen Sie pro Workspace im Workspace-Editor ein, auf dem Host, und es fällt auf NAT zurück, wenn die Schnittstelle beim Start nicht verfügbar ist. Sie treffen diese Wahl in einem Panel, nicht in einer Konfigurationsdatei, die der Agent bearbeiten kann.
Und wenn Sie den Dienst absichtlich veröffentlichen
Manchmal wollen Sie die Vorschau tatsächlich im Internet haben, für eine Kundin oder eine Kollegin. Also klicken Sie auf den Globus, öffnen den Tunnel und lassen die Scanner sie finden. Gehen Sie die Wordlist durch, Eintrag für Eintrag, und sehen Sie sich an, was zurückkommt.
.env und /proc/self/environ liefern die Umgebung des Workspace, und jede
Zugangsberechtigung darin ist eine Fälschung. Bromure leitet jeden Platzhalter
aus dem echten Wert plus einem installationseigenen 32-Byte-Salt über HKDF-SHA256
ab und behält dabei die Form, die ein clientseitiger Validator erwartet: ein
Anthropic-Schlüssel liest sich als sk-ant-api03-brm-…, ein GitHub-Token ist
ghp_ plus 36 Zeichen, GitLab ist glpat- plus 20. Bromure schreibt diese
Fälschungen in die Umgebungsvariablen und in ~/.git-credentials,
~/.docker/config.json, ~/.kube/config und die MCP-Konfigurationen. Die echten
Werte betreten die VM nie; sie bleiben verschlüsselt auf dem Mac, und ein Proxy
auf der Host-Seite tauscht jeden davon im letzten Moment auf die Leitung, jeweils
begrenzt auf den Zielhost, zu dem er gehört.
/home/ubuntu/.aws/credentials ist der schärfste Eintrag, denn /home/ubuntu
ist das Home-Verzeichnis einer Bromure-Workspace-VM. Der Scanner rät richtig,
unter welchem Benutzer der Server läuft. Die Datei ist trotzdem nicht da. Bromures
AWS-Einrichtung schreibt gar keine Credentials-Datei; sie schreibt
~/.aws/config mit einer credential_process-Zeile, die auf einen Helfer zeigt,
der über einen Host-Socket Ihre echte Access Key ID zusammen mit einem
vierzigstelligen gefälschten Secret Key ausgibt und das Session-Token
weglässt. Die AWS-SDKs, die aws-CLI, terraform und boto3 nehmen das alle von
selbst auf. Ein Scanner, der die Konfigurationsdatei liest, bekommt den Pfad
eines Helfers, den er nicht aufrufen kann.
Nehmen Sie das gefälschte Secret trotzdem, haben Sie etwas Totes genommen. Der
Gast signiert seine Anfragen mit dieser Fälschung, und der Host entfernt die
Signatur und signiert auf dem Weg nach draußen mit dem echten Schlüssel neu. Eine
Anfrage, die AWS auf irgendeinem anderen Weg erreicht, scheitert mit
InvalidSignatureException. F5s letzte Empfehlung lautet, jedes lokale Geheimnis
als kompromittiert zu behandeln und es zu rotieren. Die entsprechende Zeile in
Bromures eigener Dokumentation liest sich andersherum: weil nur die Fälschung
abgeflossen ist, muss die echte Zugangsberechtigung nie rotiert werden.
Ein Eintrag der Wordlist nennt eine Datei, die echtes Geld wert ist:
terraform.tfstate. State-Dateien liegen dort, wo das Repository liegt, also
entscheidet Ihre Liste geteilter Ordner über ihre Exposition. Host-Ordner hängen
sich als virtiofs-Mounts unter /home/ubuntu/<basename> an einen Workspace,
gedeckelt bei acht pro Workspace, und sie sind der einzige Teil des Dateisystems
Ihres Mac, den die VM erreicht. Teilen Sie das Repository, an dem der Agent
arbeitet, und sonst nichts, dann findet das Traversal ein Verzeichnis statt einer
Platte.
Die meisten Entwickler-Sicherheitsgeschichten dieses Jahres beschreiben etwas, das ankommt: ein Paket, ein Archiv, eine Dokumentationsdatei. Hier kommt nichts an. Stattdessen bitten 32.000 Anfragen im Monat einen Prozess, den Sie gestartet haben, einem Fremden Dateien vorzulesen, und der Ausgang hängt daran, welche Maschine diesen Prozess ausführt und was in ihrem Home-Verzeichnis liegt.
Setzen Sie den Entwicklungsserver des Agenten auf einen Switch, auf dem nur Ihr Mac ist, und füllen Sie sein Home-Verzeichnis mit Platzhaltern. Bromure Agentic Coding installieren, und dann lassen Sie die Scanner fragen.