Abstracte technische illustratie op een donker marineblauw vlak: een compacte serverkubus aan de linkerkant zendt drie kleine rechthoekige kaarten uit naar een agentknooppunt aan de rechterkant; de eerste twee kaarten zijn bleek en inert, de derde werpt een lange schaduw in de vorm van een sleutel. Fijne cyaankleurige filamenten lopen van de server naar een losse grid van repository-knooppunten erachter, en een enkele amberkleurige lijn verbindt het agentknooppunt met een sleutelbos van kleine schijfjes met inloggegevens. Geen mensen, geen logo's, geen tekst. Het OrcaRouter-logo is in de rechteronderhoek gecomponeerd.
AI Safety Incidents

Deadbugz: een MCP-server die bij de derde tool-call vijandig wordt, in 74 minuten naar 23 repositories gepusht

Auteur

Magnus Corvin

Publicatiedatum

Nieuwste modellen · 20Bekijk alle modellen →
Benchmarks: Artificial Analysis · dagelijks bijgewerkt
Terug naar alle berichten

Op 10 augustus 2026 opende een GitHub-account, zellkernel, 23 pull requests in 74 minuten bij niet-verwante AI-, MCP- en ontwikkelaarstooling-repositories, die elk een MCP-server toevoegden met de naam productivity-suite die twee gewone tools adverteerde: format_text en summarize. Volgens Pillar Security, dat de campagne Deadbugz noemde en zijn verslag op 12 augustus publiceerde, gaf de server bij zijn eerste drie aanroepen eerlijke resultaten terug en herschreef daarna de metadata die hij aan de agent doorgaf: de toolbeschrijvingen en de promptinhoud begonnen het model richting SSH-sleutels, AWS-referenties, shellgeschiedenis en Kubernetes-configuratie te sturen, en het te vertellen die activiteit voor de gebruiker verborgen te houden. Negentien van de 23 pull requests waren gesloten, vier stonden nog open en geen enkele was samengevoegd toen Pillar ze beoordeelde. Er is geen slachtoffer bevestigd. Dit is één record, door anderen gemeld en hier aan hen toegeschreven. De andere gedocumenteerde agent-incidenten, elk met eigen bronnen, ernst, betrouwbaarheidsgraad en betwist-markering, staan in het AI-incidentenarchief — zodat een supply-chaincampagne gericht op agent-tooling naast de rest van wat er daadwerkelijk is gebeurd kan worden gelezen.

Het archief beoordeelt dit record als hoge ernst en betrouwbaarheid A — goed gedocumenteerd, met primaire bronnen die overeenstemmen — terwijl afzonderlijk wordt vastgelegd dat er geen bevestigde werkelijke schade is. Beide dingen zijn tegelijk waar, en de kloof daartussen is waar het record over gaat: een campagne waarvan het ontwerp in ongebruikelijk detail werd gedocumenteerd voordat ze een slachtoffer voortbracht dat iemand bij naam kan noemen. De twee data die van belang zijn, liggen twee dagen uit elkaar. De pull requests werden op 10 augustus verstuurd; Ariel Fogel van Pillar Security publiceerde de analyse op 12 augustus, en de post bevat een vaste opmerking dat hij zou worden bijgewerkt zodra geverifieerde informatie binnenkwam.

Drie oproepen, daarna verandert de metadata.

Een MCP-server hoeft geen code op een machine uit te voeren om te veranderen wat een agent doet. Tooldefinities worden bij elke sessie als context aan het model doorgegeven, wat betekent dat de server die ze levert de instructies die de agent leest kan herschrijven, terwijl de naam van de tool, zijn repository en zijn manifest precies blijven zoals ze waren. Deadbugz is gebouwd op die asymmetrie, en Pillar noemt dit runtime-gated MCP metadata poisoning.

De mechaniek is klein genoeg om in één zin uiteen te zetten. De server houdt per client een teller in het geheugen bij van tools/call-aanvragen. Bij de eerste drie gedraagt hij zich normaal. Zodra de teller omslaat, komen latere tools/list- en prompts/get-antwoorden gewijzigd terug — andere toolbeschrijvingen, andere promptinhoud — die de agent naar SSH-sleutels, AWS-referenties, shellgeschiedenis en Kubernetes-configuratie sturen en hem opdragen de activiteit voor de gebruiker te verbergen. De vergiftigde prompttekst draagt de markering deadbugz en een bitcoinadres.

De gate is ook de reden waarom de gewone verdedigingen hem niet onderscheppen. De payload staat vanaf de eerste aanvraag in de bron; niets aan de code of de configuratie verandert op het moment van de omschakeling. Een statische scan, een SBOM-vermelding of een eenmalige uitlezing van het toolmanifest bij installatie ziet een opmaakhulpprogramma, omdat dat is wat het hulpprogramma retourneert tot de teller verschuift. Pillar beschrijft de vertraagde omschakeling als een techniek om onderzoek te ontwijken, en zegt dat zijn onderzoekers zowel de drempel als de gewijzigde metadata hebben bevestigd door aanvragen met alleen tekst naar de live externe dienst te sturen en de antwoorden te vergelijken met de openbare bron.

Eén detail maakt de val breder dan een enkele sessie. De server adverteert tools.listChanged, de MCP-capabiliteit die een client meedeelt dat zijn toollijst is herzien. Een client die dat signaal respecteert, leest de definities midden in de sessie opnieuw en haalt de vergiftigde versie binnen zonder enige actie van de operator; een client die definities bij goedkeuring cachet, doet dat niet. Welk gedrag een bepaald agent heeft, is een eigenschap van de client, niet van de server, en Pillars uiteenzetting noemt clients niet met naam.

HTML card titled 'Three calls, then the metadata changes', kicked 'MCP · productivity-suite', with the subtitle 'The payload is present from the first request; the gate is a counter in memory'. Three columns. 'Calls one to three — benign' lists format_text returning formatted text, summarize returning a summary, and tools/list and prompts/get returning honest tool definitions, with a note that nothing on disk differs from what a reviewer approved. 'The gate' lists an in-memory per-client counter of tools/call requests, a threshold of three, altered tool descriptions and prompt content in later tools/list and prompts/get responses, and the advertised tools.listChanged capability that lets compliant clients re-read definitions mid-session. 'What the poisoned metadata asks for' lists SSH keys, AWS credentials, shell history and Kubernetes configuration, an instruction to keep the activity from the user, and the embedded marker deadbugz with a Bitcoin address. A footer reads 'Per Pillar Security's disclosure of 12 August 2026. Pillar says its researchers confirmed the threshold and the altered metadata against the live remote service using text-only requests, matching the public source.'

Oplevering: 23 pull requests in 74 minuten

De distributie was geen pakket in een registry of een vergiftigde afhankelijkheid die in een lockfile begraven lag. Het was pull-requestspam tegen projecten die niets te maken hadden met de vermeende functie van de server; dat is de vorm die een goedkope poging tot een supplychainaanval aanneemt wanneer de aanvaller geen maintaineraccount kan krijgen: genoeg configuratiewijzigingen indienen en wachten tot er één wordt samengevoegd of lokaal wordt toegepast.

Pillars uiteenzetting van de 23 valt uiteen in drie categorieën. Zeventien voegen een extern MCP-eindpunt toe, productivity-suite-mcp[.]onrender[.]com/mcp, gehost op Render; vier roepen een verborgen lokaal Python-bestand aan op ~/.config/.cache/.sys/.deadbug-mcp.py; twee zijn inzendingen voor directory's of lijsten, die het verslag als verkenning of opvulling behandelt en niet als levering. Het tijdvenster wordt genoemd als 9:52 PM tot 11:07 PM UTC op 10 augustus 2026 — 74 minuten in de formulering van de openbaarmaking, hoewel de twee tijdstempels zelf 75 minuten omspannen, en niets in het verslag draait om die minuut. Slechts één doelrepository wordt afzonderlijk genoemd: getsentry/sentry-mcp, pull request #1239, aangehaald als een voorbeeld van de levering via een lokaal artefact.

Het account erachter was aanzienlijk voor zijn leeftijd. Op het moment van Pillars verzameling had zellkernel 50 openbare repositories, waarvan 20 forks, en 21 van die 50 waren op 10 augustus aangemaakt, dezelfde dag als de campagne. Het profiel was gekoppeld aan het X-account @llmgod, dat terugverwees naar het GitHub-account, wat het soort wederzijdse verwijzing is dat pleit voor een doelbewust opgezette identiteit, niet voor een gekaapte.

Negen­tien gesloten, vier open, nul samengevoegd is het meest herhaalde cijfer in het verslag en ook het cijfer dat meestal als groen licht wordt gelezen, wat het niet helemaal is. De samenvoegknop van GitHub is geen uitvoeringsregistratie van een host: een maintainer kan een branch ophalen en uitvoeren, een configuratie handmatig toepassen, of een CI-job kan de head van een PR ophalen voordat iemand reageert. De vier pull requests die een configuratie schrijven die een lokaal scriptpad aanroept, zijn de gevallen waarin die kloof het zwaarst weegt, omdat het script volledig buiten de samenvoegadministratie van GitHub wordt opgehaald en uitgevoerd. Cloud Security Alliance Labs maakte hetzelfde punt in zijn notitie van 2 september: de aantallen gesloten en niet-samengevoegd bewijzen niet dat er niets is uitgevoerd.

HTML card titled 'Twenty-three pull requests in seventy-four minutes', kicked '10 August 2026 · delivery', subtitled 'Times UTC. Counts are Pillar Security's review snapshot.' Three columns. 'The window' lists the first pull request at 21:52, twenty-three pull requests to unrelated AI, MCP and developer-tooling repositories, the last at 23:07, and a note that the 74-minute framing spans 75 minutes on the clock. 'What each pull request added' lists seventeen adding the remote endpoint productivity-suite-mcp.onrender.com/mcp, four invoking the hidden file at ~/.config/.cache/.sys/.deadbug-mcp.py, two directory or listing submissions, and one named example, getsentry/sentry-mcp pull request 1239. 'At review' lists nineteen closed, four open, zero merged through GitHub's review, zero confirmed victims, and the account zellkernel linked to the X handle llmgod, with fifty public repositories and twenty-one created that day. A footer reads 'Per Pillar Security. Cloud Security Alliance Labs repeated the same figures on 30 August and 2 September 2026 without independent verification. As of 29 October 2026 the GitHub account and the productivity-suite-mcp repository both return 404.'

Wat is vastgesteld, en wat niet

Vastgesteld op basis van de openbaarmaking, in die zin dat Pillar het rapporteert uit artefacten die het heeft gelezen en in één geval uit een service die het heeft bevraagd: de server en zijn bronrepository, de twee aangekondigde tools, de teller en de drempel van drie aanroepen, de vier credential-doelen, de PR-aantallen en hun samenvoegstatus op het moment van beoordeling, en de koppeling tussen het GitHub-account en de X-handle. Pillars eigen tests tegen het live-eindpunt vormen het sterkste item op de lijst, omdat ze een reproductie zijn en niet het lezen van broncode.

Niet vastgesteld, en het verslag is daar zorgvuldig over: een slachtoffer. Het real_harm-veld van het archief staat op false, en dat is een uitspraak over bewijs, niet over intentie — niemand heeft een host, een log of een gestolen credential geproduceerd die aan deze campagne gekoppeld is. Ook de persoon of groep achter zellkernel en @llmgod is niet geïdentificeerd; Pillar schrijft de operatie toe aan de accounts en stopt daar. Het financiële motief rust op een Bitcoin-adres dat in de payload is ingebed, wat een gevolgtrekking uit een indicator is, niet een bevinding over de actor. En de vraag die een verdediger het liefst beantwoord zou zien — of de campagne nog steeds loopt — heeft geen antwoord in het verslag: de post was gemarkeerd als een bericht dat zou worden bijgewerkt, en er is geen latere revisie of verwijderingsmelding van GitHub of Render zichtbaar.

De onderbouwing is dunner dan het vertrouwensniveau zou doen vermoeden, en dat mag ronduit gezegd worden. Twee Cloud Security Alliance Labs onderzoeksnotities, gedateerd 30 augustus en 2 september 2026, herhalen de campagne; de latere stelt expliciet dat die Pillar de ontdekking, de PR-details, het servergedrag en de accountattributie toeschrijft, en beschrijft geen eigen onafhankelijke verificatie. Een Armor blogpost van 22 september 2026 biedt defensieve richtlijnen en stelt dat Pillar de server uit elkaar heeft gehaald; die biedt geen eigen forensisch bewijs. Er werd geen CVE toegewezen, en CSA zegt dat dit geen kwetsbaarheid in de MCP-specificatie is. Per 29 oktober 2026 leveren zoekopdrachten geen enkele advisory van GitHub of Render op, en geen berichtgeving in de reguliere securityvakpers — geen enkel artikel van BleepingComputer, The Register, SecurityWeek of Hackread — wat ongewoon is voor een supply-chaincampagne van deze vorm en zelf deel uitmaakt van wat het dossier toont. "Primaire bronnen zijn het eens" betekent hier één oorspronkelijke primaire bron en een reeks secundaire documenten die daarvan afgeleid zijn.

Twee kleinere ambiguïteiten zijn het waard om te markeren plutôt dan ze weg te gladden. Secundaire samenvattingen verschillen in hun weergave van de vraag of de derde dan wel de vierde aanroep de eerste is die vergiftigde metadata ontvangt, wat volgt uit het feit dat de teller volgens de beschrijving bij de derde aanvraag omslaat; zowel het verslag als de openbaarmaking gebruiken drie. En het leveringsvenster wordt beschreven als 74 minuten voor tijdstempels die een bereik van 75 minuten omspannen.

Eén controle die niet kon worden herhaald: op 29 oktober 2026 geven het GitHub-account zellkernel en de repository zellkernel/productivity-suite-mcp beide 404, en de enige afzonderlijk genoemde pull request, getsentry/sentry-mcp #1239, is ook niet meer te vinden — de repository zelf verwijst nu door naar getsentry/toolkit. De PR-aantallen, de merge-status en de inhoud van de repository kunnen daarom vandaag niet meer direct bij de bron worden geverifieerd; ze blijven staan als Pillar's snapshot, opgenomen medio augustus.

HTML card titled 'What is established, and what is not', kicked '2026-08-10-deadbugz-mcp-supply-chain', subtitled 'One record, one originating source, two secondary notes that restate it'. Three columns. 'Established by the disclosure' lists the server, its source repository and the two advertised tools; the counter and the three-call threshold, confirmed against the live endpoint; the four credential targets; twenty-three pull requests, nineteen closed, four open, none merged; and the delivery account linked to the X handle llmgod. 'Not established' lists any victim or executed payload, with the archive recording real harm as false; the actor behind the account and handle; motive, which rests on a Bitcoin address in the payload; and whether the campaign is still running, the post having promised updates that are not visible. 'Corroboration' lists the Cloud Security Alliance Labs notes of 30 August and 2 September 2026 as restatement without independent checks; the Armor blog of 22 September 2026 as guidance without forensic evidence; no CVE assigned; no GitHub or Render advisory found; and no mainstream trade-press coverage found as of 29 October 2026. A footer reads 'The archive grades the record A, well documented with primary sources that agree. The secondary documents here all derive from Pillar Security's post, so agreement between them is not a second measurement.'

Wat de openbaarmaking verdedigers vraagt te doen

De reactie die Pillar aanbeveelt gaat grotendeels over het behandelen van metadata als een beveiligingsoppervlak, niet als een beschrijving daarvan. Voor hosts zijn de concrete opdrachten om te blokkeren of te jagen op productivity-suite-mcp[.]onrender[.]com/mcp, het eerdere trycloudflare.com-eindpunt van de campagne op deny- en huntinglijsten te houden, hoewel Pillar zegt dat het momenteel niet actief is, en niet uit te voeren deadbug-mcp.py — het verborgen bestandspad ~/.config/.cache/.sys/.deadbug-mcp.py is het artefact waarnaar gezocht moet worden in homedirectory's, repositories en MCP-clientconfiguraties.

De volgorde van het onderzoek is belangrijker dan de blokkeerlijst. Als een host mogelijk verbinding heeft gemaakt, zegt Pillar dat je MCP-clientlogs moet bewaren voordat je iets opruimt, en daarna de vernieuwingen van tooldefinities moet bekijken en wat de agent na de derde aanroep deed; inloggegevens mogen alleen worden geroteerd waar lokaal bewijs blootstelling ondersteunt, wat het tegenovergestelde is van de reflex om alles bij verdenking te roteren. De configuratie van de server liet ook optionele telemetrie toe naar een WEBHOOK_URL, met beaconing bij verbinding, eerste aanroep en trigger-event — een detail dat een onderzoek een derde plek biedt om te kijken, naast clientlogs en endpointverkeer.

Voor de mensen die MCP-clients bouwen, is de aanbeveling structureel, en het is het deel van het record dat het langst houdbaar blijft:

• Maak bij goedkeuring een fingerprint van tooldefinities en vergelijk deze bij elke verversing, in plaats van te vertrouwen op de naam en repository van de server.

• Behandel een wijziging van een definitie op een reeds goedgekeurde server als een beveiligingsgebeurtenis die de operator ziet en opnieuw goedkeurt, en niet als routineuze metadatamutaties die stilzwijgend worden doorgelaten.

Dwing gevoelige bewerkingen — toegang tot inloggegevens, code-uitvoering, uitgaande e-mail, schrijfbewerkingen naar repositories — af via beleid, niet via beschrijvingen die de server levert.

Dat derde punt is wat van Deadbugz een record maakt eerder dan een curiositeit. Elke controle hierboven gaat ervan uit dat een agent dingen kan worden aangepraat door de tekst die een server aan een tool hangt, en dat die tekst kan veranderen nadat de vertrouwensbeslissing is genomen. Pillar plaatst de campagne in een reeks die Invariant Labs' MCP-sleeper-aanval van 2025 omvat, het nagemaakte postmark-mcp-pakket en een door Koi gedocumenteerd MCP-pakket dat via een update is bewapend — allemaal precedenten voor de techniek, door Pillar daarvoor aangehaald en niet als bewijs over deze levering.

Waarom de gate belangrijker is dan het aantal slachtoffers

Een campagne met 23 leveringspogingen, geen merge en geen bevestigd slachtoffer is makkelijk onder 'gepoogd' te archiveren en verder te gaan. De reden dat ze met hoge ernst in het archief thuishoort, is dat haar ontwijking niet afhangt van het slagen van de levering op schaal. Ze hangt af van een eigenschap die de meeste MCP-implementaties vandaag de dag delen: goedkeuring gebeurt één keer, bij de installatie, en men gaat ervan uit dat de definitie die werd goedgekeurd, ook de definitie is die wordt uitgeleverd. Deadbugz houdt die aanname drie calls lang intact en doorbreekt ze dan.

De oplossing is geen patch voor een specifieke server, en er is geen CVE om te volgen. Het is dat "approved" een blijvende voorwaarde moet worden met een vergelijking erachter — wat een verandering is in hoe clients en hun operators zich gedragen, niet in wat een scanner zoekt. Of iemand de server in augustus daadwerkelijk heeft laten draaien, is nog steeds onbekend; op grond van wat er nu vastligt, is het mechanisme de bevinding.