Die Doku nannte ein Paket, das niemandem gehörte
Forscher haben 6.214 Firmendomains nach llms.txt durchsucht, jener maschinenlesbaren Datei, die Unternehmen heute für KI-Agenten veröffentlichen, und darin 237 genannte Pakete und Domains gefunden, die nie jemand registriert hatte. Ein paar davon haben sie selbst genommen. Der erste Coding-Agent in einem Fortune-500-Netz installierte eines davon in unter vier Minuten. Der Angreifer hat weder einen Maintainer noch eine Registry noch ein Repository angefasst. Die Altersschwelle von Bromure Agentic Coding ist ab Werk bei zwei Tagen aktiv, und ein Name, den ein Angreifer belegt, ist konstruktionsbedingt ein brandneuer Publish.
Ein Anbieter schrieb in seine eigene Dokumentation einen Installationsbefehl für ein Paket, das er nie veröffentlicht hat. Der Name lag dort, frei, für jeden zu haben. Coding-Agenten lasen die Doku, glaubten ihr und führten die Installation aus.
Irgendwann in den letzten zwei Jahren begannen Ihre Entwicklerwerkzeuge, eine
neue Datei auszuliefern. Sie liegt neben robots.txt, sie heißt llms.txt, und
sie enthält eine Zusammenfassung des Produkts in reinem Text, geschrieben für
eine Maschine statt für einen Menschen. Was die API tut. Welche Endpunkte zählen.
Welches Paket man installiert, um loszulegen. Coding-Agenten holen sie sich, und
weil sie von der eigenen Domain des Anbieters kommt, behandeln sie sie als
gesicherte Tatsache.
Ein Forscher namens Alon Hertz, der unter dem Namen PANDEX arbeitet, sah nach,
was diese Dateien einem Agenten aufzutragen. Seine Methode braucht drei Schritte
und keinen Exploit: llms.txt und llms-full.txt aus Firmenverzeichnissen
ziehen, echte Agenten in Sandboxes darauf ansetzen und beobachten, wonach die
Agenten greifen, dann jeden Paketnamen und jeden Hostnamen, der dabei
herauskommt, gegen npm, PyPI und die Domain-Registries prüfen. Er beschreibt das
Werkzeug auf whatwouldai.do, unter einem Slogan, der
sich als der Befund entpuppte: Agenten handeln auf alles hin.
Der Scan umfasste 6.214 aktive Domains aus Fortune-500-Konzernen, Big Tech, Fintech und Rüstungsunternehmen sowie mehr als 8.000 dieser Dateien. In 120 davon existierte das, was die Datei dem Agenten zu installieren auftrug, gar nicht. Über den gesamten Korpus hinweg lagen 237 genannte Paketnamen und Hostnamen frei: verfügbar auf npm, PyPI, RubyGems, NuGet, crates.io und Packagist, oder frei als Subdomains bei Vercel, Render, Fly und Netlify. Jeder konnte sie zum Preis einer Anmeldung nehmen.
Also nahmen die Forscher eine Handvoll, veröffentlichten unter diesen Namen harmlose Pakete mit einem Beacon, das beim Installieren nach Hause funkt, und warteten.
Der erste Rückruf traf in unter vier Minuten ein. Der zweite kam binnen einer Stunde. Über den folgenden Zeitraum protokollierten sie Installationen aus Dutzenden Organisationen, mehrere davon Fortune-500-Umgebungen, ausgelöst von Agenten auf Anthropics Claude, OpenAIs Codex und Nous Researchs Hermes. Bruce Schneier griff die Studie am 4. September auf und las sie so, wie sie es verdient: Die Grenze zwischen Daten und ausführbarem Code löst sich auf. Ein in diesem Beitrag zitierter Forscher braucht weniger Worte. „Das Vertrauensmodell ist kaputt.“ Agenten „behandeln Anbieterdokumentation als Grundwahrheit und hinterfragen sie nicht“.
Clerk dokumentierte ein Paket, das es nie ausgeliefert hat
Das klarste Beispiel kommt von einem Authentifizierungsanbieter, dessen Dokumentation dem Leser sagt, er solle Folgendes ausführen:
npx clerk-next-fix-auth-protection
Clerk hat nie ein eigenständiges Paket unter diesem Namen veröffentlicht.
Vielleicht war der Befehl eine Abkürzung, vielleicht zeigte er auf etwas
Internes, vielleicht hat sich ein Autor vertan. Der Grund spielt keine Rolle,
denn für einen Agenten las sich der Name echt. Jemand anderes hat ihn
registriert. Advisory-Datenbanken führen dieses Paket inzwischen als
MAL-2026-11069, und es tat, was man für Aufklärung baut: Die
npm-Installationshooks feuerten und schickten den Benutzernamen des
installierenden Kontos, den Hostnamen der Maschine, das Arbeitsverzeichnis und
einen Zeitstempel hinaus.
Das ist eine Karte der Build-Umgebung von jemandem, gesammelt innerhalb seines Netzwerks durch seinen eigenen Coding-Agenten, der der Doku seines eigenen Anbieters folgte.
Warum der übliche Rat direkt auf die Payload zeigt
Jeder Supply-Chain-Leitfaden sagt Ihnen, Sie sollen einen Paketnamen gegen die offizielle Dokumentation prüfen. Dieser Rat versagt hier, denn die offizielle Dokumentation ist genau der Ort, aus dem der schlechte Name stammt.
Drehen Sie das Problem um, über das wir im Juli geschrieben haben, und Sie bekommen dieses. Dort halluziniert ein Agent einen plausiblen Paketnamen, und ein Angreifer registriert die Namen, die er zu erfinden pflegt, der schwache Schritt ist also die Vermutung des Modells. Hier vermutet das Modell nichts. Es geht zum Anbieter, liest, was der Anbieter sagt, folgt dem, und genau diese sorgfältige Abfolge erwischt es.
Eine Registry-Kompromittierung hat ebenfalls eine andere Form. Als ein Release-Workflow zehn vergiftete Versionen eines echten Pakets veröffentlichte im vergangenen Monat, musste erst etwas brechen: ein Workflow, der einem Kommentar vertraute. Hier bricht nichts. Ein Technischer Redakteur tippt einen Befehl, der nicht ganz zu einem veröffentlichten Artefakt passt, was der gewöhnlichste Fehler der Softwarewelt ist, und die Lücke zwischen Name und Artefakt wird zu einem Ausführungsprimitiv, das jeder im Internet aufheben kann.
Die Schicht, die das abfängt, ist schon an
Bromure Agentic Coding führt jeden Coding-Agenten in einer hardwarevirtualisierten Linux-VM auf Ihrem Mac aus, und jedes Paket, das der Agent holt, läuft durch einen Proxy auf der Host-Seite dieser Grenze, bevor ein einziges Byte die VM erreicht. Dort greifen mehrere Schichten. Für diese Geschichte erledigt eine davon die Arbeit im Alleingang, und es ist genau die, die ein neuer Arbeitsbereich bereits eingeschaltet hat.
Die Altersschwelle macht aus einem frisch belegten Namen ein Nicht-Ereignis.
Ein Arbeitsbereich verweigert Paketversionen, die jünger sind als eine Grenze,
die ab Werk bei zwei Tagen liegt. Der Proxy setzt das durch, indem er die
Versionsliste der Registry im Vorbeigehen umschreibt: Er entfernt Versionen, die
jünger als die Grenze sind, und zeigt latest neu auf die jüngste
Überlebende. Ein Paket, das heute Morgen zum ersten Mal veröffentlicht wurde, hat
keine Version, die alt genug wäre, um diesen Filter zu überstehen, aus Sicht des
Agenten gibt es unter diesem Namen also nichts zu installieren. Fragt der Agent
direkt nach einer zu frischen Version, kommt der Abruf als HTTP 451 zurück,
dessen Body das echte Alter des Pakets und das geforderte Minimum nennt, und npm
gibt diesen Text wortwörtlich aus.
Lesen Sie den Angriff mit diesem Baustein noch einmal. Die gesamte Technik hängt daran, dass ein Name zu einem vom Angreifer gewählten Zeitpunkt von unpubliziert zu publiziert wechselt. Dieser Übergang ist ein brandneues Release. Die eine Eigenschaft, der der Angreifer nicht ausweichen kann, ist genau die, an der die Standardrichtlinie ansetzt.
Das Entfernen von Installationsskripten nimmt genau den Mechanismus weg, den
die Payload nutzte. Das beobachtete Paket erledigte seine Arbeit in den
npm-Hooks preinstall, install, postinstall und prepare. Mit aktiviertem
Skript-Stripping entpackt der Proxy jedes npm-Tarball im Flug, löscht diese vier
Schlüssel aus der package.json, entfernt dist.integrity und dist.shasum aus
den Metadaten, damit npms eigene Hash-Prüfung weiterhin durchgeht, und packt
wieder ein. Das Paket installiert sich; das Beacon hat nichts mehr, woraus es
starten könnte. Pakete, die ihre Hooks brauchen, etwa Compiler nativer Bindings
wie better-sqlite3, kommen auf eine Allowlist pro Arbeitsbereich und behalten
sie.
Die Reputationsfilterung kennt dieses Paket beim Namen. MAL-2026-11069 ist
ein Malware-Advisory. Mit socket.dev als gewähltem Paketfilter des Arbeitsbereichs
greift dessen Sperre für kompromittierte Pakete bei Malware- und
Typosquat-Signalen in jeder Schwere; die kostenlose OSV-Prüfung deckt alle acht
abgefangenen Ökosysteme ohne API-Schlüssel ab. Wenn eine Reputationsquelle kein
Urteil liefern kann, sei es durch Rate Limiting, ein weggebrochenes Netz oder ein
Ökosystem, das sie nicht abdeckt, fällt Bromure geschlossen aus, statt den Abruf
zuzulassen. Der Download pausiert und fragt Sie, pro Paket und Version, sodass
ein Angreifer, der einen Abfragefehler auslösen kann, nichts gewinnt.
Die Aufklärung, die es einsammelt, gehört der VM. Jede Schlagzeile zu dieser Studie sagt dasselbe: Agenten installieren unbekannten Code in Unternehmensnetzen. Die Ernte des Beacons war der installierende Benutzername, der Hostname der Maschine und das Arbeitsverzeichnis. In einem Bromure-Arbeitsbereich beschreiben diese drei Felder einen Linux-Gast auf Ihrem Mac und nicht einen domänengebundenen Build-Host mit einem internen Namen, der sich für eine Zielliste lohnt. Die Zugangsdaten, die in dieser VM liegen, sind Attrappen, deren echte Werte nur im Speicher des Host-Proxys existieren. Versucht feindlicher Code doch, eine davon zu einem Host zu tragen, für den sie nicht geprägt wurde, blockiert der Proxy die Anfrage und pausiert die VM mitten im Flug.
Default Deny beantwortet die andere Hälfte der Studie. Etliche der freien Namen waren Hostnamen statt Paketen: abgelaufene Domains und kostenlose Subdomains bei Vercel, Render, Fly und Netlify, die in Dokumenten stehen, die Agenten abrufen. Die Egress-Firewall des Arbeitsbereichs ist eine geordnete Regeltabelle mit einer Einstellung Unmatched traffic; setzen Sie sie auf Deny, und die VM öffnet Verbindungen zu den von Ihnen gelisteten Hosts und zu nichts sonst, auf jedem Protokoll. Zwei Komponenten setzen das außerhalb des Gastes durch: Der virtuelle Netzwerk-Switch prüft jeden Fluss anhand der Ziel-IP-Adresse, und der Host-Proxy prüft noch einmal anhand des TLS-Servernamens. Ein Beacon, das auf eine Domain zielt, die jemand vergangenen Dienstag registriert hat, verlässt die Maschine nicht. Regeländerungen erreichen laufende Sitzungen ohne Neustart.
Jeder Versuch bekommt eine Zeile. Auf der Trace-Stufe Activity only
schreibt der Proxy einen Metadatensatz pro Anfrage aus der VM, mit Zeitstempel,
Host, Port, Methode, Pfad, Status, Latenz und Bytes, und er speichert überhaupt
keine Request-Bodies. bromure-cli trace hostnames my-workspace gibt jeden
einzelnen Host aus, den der Arbeitsbereich kontaktiert hat, mit Zählern. Sie
sehen eine Rückruf-Domain, die keiner Ihrer Ingenieure kennt, an dem Tag, an dem
es passiert, auf Ihrer eigenen Maschine, statt Monate später im Datensatz eines
Fremden davon zu lesen.
Was schon an ist
Ein neuer Arbeitsbereich kommt mit aktivierter Altersschwelle bei einem
Minimum von zwei Tagen, und genau in diese Einstellung läuft dieser Angriff.
Heben Sie sie an, wenn Ihre Arbeit das Warten verträgt, bis zu 90 Tage auf
dem Stepper, und nutzen Sie Exempt packages für die Pakete, die Ihr
eigenes Team in derselben Stunde veröffentlicht und installiert, in der Form
npm:unser-paket.
Was sich heute einzuschalten lohnt
Aktivieren Sie im Bereich Supply Chain des Arbeitsbereichs das Entfernen von Installationsskripten und wählen Sie einen Paketfilter. Setzen Sie unter Guardrails Unmatched traffic auf Deny und listen Sie die Hosts, die der Job braucht. Unter Tracing behält Activity only die Spur der kontaktierten Hosts und nichts vom Inhalt. Jede dieser Änderungen gilt für bereits laufende Sitzungen.
Niemand liest eine Datei Korrektur, die für Maschinen geschrieben ist
Der PANDEX-Scanner jagt noch etwas. Neben unbeanspruchten Paketen und Domains
sucht er nach Anweisungen, die an den Agenten statt an den Leser gerichtet sind:
Direktiven, die in die Datei gepflanzt wurden, manchmal mit Unicode-Tricks und
Zeichen der Breite null versteckt. Die Build-Pipeline eines Anbieters erzeugt
llms.txt, Ihr Agent konsumiert es, und niemand in einer der beiden Firmen liest,
was da zwischen ihnen hin und her ging.
Bromure behandelt eine abgerufene Seite als nicht vertrauenswürdige Eingabe.
Inhalte, die der Agent von außen hereinzieht, seien es Dateiinhalte, Webseiten,
Issue-Texte oder Kommandoausgaben, erreichen das Modell als tool_result-Span.
Mit aktiviertem Quellcode-Detektor bewertet ein PromptGuard-Modell auf Ihrem Mac
diese Spans auf der Leitung, bevor das Modell darauf handelt, und Sie entscheiden,
ob es protokolliert, fragt oder blockiert. Kein Inhalt geht irgendwohin, um
geprüft zu werden.
Wir haben ein Jahrzehnt damit verbracht zu lernen, Artefakte zu verifizieren: das Paket signieren, den Hash pinnen, den Build attestieren. Diese Studie handelt vom Schritt davor, dort, wo ein Agent entscheidet, nach welchem Artefakt er fragt, und dabei von einem Dokument ausgeht, das keine Signatur trägt und von einem technischen Redakteur in Eile geschrieben wurde. Dokumentation ist zu einer ausführbaren Eingabe geworden, und die Registries sind voll freier Namen, die darauf warten, dass jemand bemerkt, dass ein Anbieter sie erwähnt hat.
Greppen Sie Ihre eigene llms.txt nach Namen, die Sie nie veröffentlicht haben.
Das ist die Arbeit eines Vormittags und nimmt Sie von der Zielliste eines
anderen. Geben Sie Ihrem Agenten dann eine Maschine, auf der ein vor vier Minuten
veröffentlichtes Paket nicht installierbar ist und auf der Sie sehen können,
wohin er überall gegangen ist. Installieren Sie Bromure Agentic Coding
und legen Sie den Installationspfad auf den Host.