Onderzoekers claimden pakketnamen die in de officiële llms.txt-bestanden van grote bedrijven stonden maar nooit waren geregistreerd, en binnen vier minuten draaide hun code in een Fortune 500-netwerk, meldt Ars Technica.
Dat raakt elke organisatie die een codeeragent laat meewerken. Zo'n agent zoekt zelf de documentatie van een leverancier op, ziet daar een regel als pip install company-sdk staan en voert die uit. Hij controleert niet of dat pakket ooit door die leverancier is vastgelegd. Andersom geldt hetzelfde: de documentatie die je zelf publiceert voor AI-agents is een installatiepad naar de machines van je klanten geworden. Twee vragen liggen daarmee op tafel. Wat staat er in je eigen agent-bestanden, en wat mag een agent bij jou zonder tussenkomst installeren.
120 bestanden, 227 commando's naar niets
Een Israëlische startup die publiceert onder de naam Pandex Research haalde ruim 8.500 llms.txt- en llms-full.txt-bestanden op van 6.214 actieve domeinen, uit een lijst van zo'n 15.000 gecatalogiseerde bedrijven: Fortune 500-namen, techreuzen, fintechs en defensieleveranciers. Op 120 van die bestanden, elk op een andere site, stonden 227 commando's die naar pakketten of domeinen wijzen die nooit zijn geregistreerd. De vrije namen lagen verspreid over PyPI, npm, RubyGems, NuGet, crates.io en Packagist, aangevuld met verlopen .dev- en .io-domeinen en losgelaten subdomeinen bij Render, Vercel, Fly en Netlify.
Om te meten wat er dan gebeurt, registreerden de onderzoekers een handvol van die namen en zetten er een pakket op dat niets deed behalve terugbellen naar hun eigen server. De eerste melding kwam binnen vier minuten, vanuit een bedrijf met een marktwaarde in de honderden miljarden. Een tweede Fortune 500-melding volgde binnen het uur, daarna nog enkele tientallen van startups en grote ondernemingen. De keten van bovenliggende processen legde vast welke programma's de installatie startten: Claude, OpenAI's Codex en Hermes van Nous Research. Anthropic, OpenAI en Nous Research reageerden niet op vragen van Ars Technica.
Er was bijzonder weinig sturing voor nodig. De onderzoekers gaven vijf modelconfiguraties en twee agentische commandoregelprogramma's honderd keer dezelfde opdracht van een zin, waarin alleen de naam van de leverancier stond. Geen link, geen documentatiepad, geen woord over llms.txt. De agents zochten dat bestand zelf op, want het opzoeken van de officiële documentatie van een leverancier is precies waarvoor ze gebouwd zijn.
Dit is iets anders dan een gehallucineerde pakketnaam
Het lijkt op slopsquatting, maar het mechanisme staat omgekeerd. Daar verzint je codeertool zelf een pakketnaam die niet bestaat en legt een aanvaller die naam vooraf vast. Hier hallucineert het model niets. De naam staat correct gespeld in een echt bestand, op het echte domein van het bedrijf, geserveerd over HTTPS, in een formaat dat speciaal is bedoeld voor machines. Alleen is het pakket erachter nooit aangemaakt.
"In een prompt-injectie plant iemand bewust kwaadaardige instructies", legt onderzoeker Alon Hertz uit tegenover Ars Technica. Hier kan de instructie volkomen onschuldig zijn en uit een legitieme bron komen. Het gevaar ontstaat pas later, wanneer het pakket of domein waar die regel naar wijst wordt losgelaten en iemand anders het claimt.
Hoe die dode verwijzingen in de bestanden terechtkwamen, is niet vastgesteld. Een deel dateert van voor de AI-golf en stond eerder al in gewone documentatie, wat wijst op mensenwerk. De onderzoekers vermoeden dat de rest door AI is gegenereerd.
De vertrouwensketen loopt ook door. Zo'n bestand hoeft niet op je eigen site te staan: een agent haalt context uit de documentatie van een partner, de SDK-referentie van een leverancier of de opzetgids van een communityproject. Vertrouwt de agent die derde partij, dan werkt de keten precies hetzelfde.
Het is al een keer echt misgegaan
Tijdens het doorspitten van de bestanden stuitten de onderzoekers op een levend geval bij Clerk, een authenticatieleverancier waarvan de SDK's onder een groot deel van de Next.js-apps in productie liggen. De agentdocumentatie van Clerk wees naar een reparatiecommando:
npx clerk-next-fix-auth-protection
Dat is geen verkeerd gespelde pakketnaam. Het is het commandoregelprogramma dat meekomt in Clerks eigen pakket @clerk/eslint-plugin. Draai je het kale commando voordat dat pakket lokaal staat, dan zoekt npx de naam op in het publieke npm-register, waar Clerk hem nooit apart had gepubliceerd. Iemand anders deed dat wel.
Het pakket dat daar kwam te staan bevatte geen werkende code. Het vuurde bij installatie meteen zijn preinstall- en postinstall-hooks af en stuurde de gebruikersnaam, de machinenaam, de werkmap en een tijdstempel over gewone HTTP naar een externe server. OSV.dev catalogiseert het als kwaadaardig onder MAL-2026-11069, met CWE-506 voor ingebedde kwaadaardige code, bevestigd door zowel OpenSSF Package Analysis als Amazon Inspector. Clerk heeft het na melding opgelost en houdt de naam nu zelf in het npm-register.
Je endpointbeveiliging ziet hier niets
Dit is het onaangename deel voor iedereen met een beveiligingsbudget. Voor een EDR-pakket of een proxy ziet zo'n installatie eruit als een ontwikkelaar die een normale pakketbeheerder gebruikt: pip install vanaf pypi.org, een domein dat elke bedrijfsproxy toestaat, met als bovenliggend proces de codeeragent die het bedrijf zelf heeft uitgerold. Geen afwijking, geen melding. De fout zit stroomopwaarts, in het gat tussen de instructie en de uitvoering, en daar kijkt het endpoint niet.
Wat er vandaag te regelen valt
Twee dingen zijn nu concreet te doen. Haal je eigen llms.txt, llms-full.txt en publieke documentatie erbij en loop elk install- of opzoekcommando na: bestaat het genoemde pakket echt, staat het onder jouw naamruimte, en leeft het domein waarnaar je verwijst nog. Dat is een controle van een half uur voor de meeste organisaties.
Leg daarnaast vast wat een codeeragent zelfstandig mag installeren. Laat hem draaien in een omgeving die je kunt weggooien, houd productiesleutels uit zijn shell, en zet installatiescripts uit waar dat kan. De FBI adviseerde eerder al om een minimale pakketleeftijd van zeven dagen aan te houden voordat een nieuwe afhankelijkheid je pijplijn in mag, en dezelfde reflexen als afhankelijkheden pinnen en herkomst verifiëren werken ook tegen dit gat.
Het aantal van deze bestanden gaat maar een kant op. Google controleert in Lighthouse of een site een llms.txt heeft, in een categorie die het Agentic browsing audits noemt, en adviseert iedere site het bestand in de hoofdmap te zetten. De onderzoekers noemen llms.txt zelf de eerste losse draad, niet het hele probleem: een agent leest ook GitHub-repositories, forums, tickets en e-mail, en alles wat hij leest is invoer die een instructie kan worden. Twintig jaar lang was gepubliceerde tekst per definitie ongevaarlijk, dus bouwde niemand integriteitscontroles omheen. Precies die aanname is deze week gesneuveld.
Veelgestelde vragen
Agents met duidelijke grenzen
Ik zet AI-agents in die echt werk overnemen, maar altijd met vastgelegde rechten, een wegwerpomgeving en secrets buiten bereik. Van meedenken en ontwerp tot bouwen en beheren, self-hosted waar dat kan.
Dit artikel is geproduceerd samen met het Agent Team. Meer over de redactie.
