·7m leestijd·1,243 woorden·

De MCP-supply chain is de nieuwe npm, en hij is al vergiftigd

Een config-to-command RCE zit ingebakken in elke officiële MCP-SDK: 7.000+ servers, 150M+ downloads, en Anthropic noemt het verwacht gedrag. Het npm-draaiboek vond zojuist de tool-lijst van je agent.

npm heeft ons alles geleerd wat we moesten weten over het vertrouwen op andermans code. We hebben er niets van meegenomen.

Het Model Context Protocol bestaat amper twee jaar en heeft nu al een pakket-ecosysteem: duizenden servers, concurrerende registries, een marktplaats of drie, en een cultuur waarin je alles klakkeloos installeert, waar een JavaScript-ontwikkelaar uit 2015 zich meteen thuis zou voelen. Het heeft ook de beveiliging van die tijd. In april publiceerde OX Security de onthulling die een eind aan het feestje had moeten maken.

Dat gebeurde niet.

De hele bug, in één alinea

Eén architectuurkeuze in de officiële MCP-SDK van Anthropic geeft je directe config-to-command execution via de STDIO-transport. Geef het een commando en het draait op de host. Start dat commando toevallig een geldige STDIO-server, dan krijg je een handle terug. Zo niet, dan krijg je een error, nadat het commando al is uitgevoerd.

Dat is het. Dat is de fout. Het is geen typo in één library. Het zit in elke officieel ondersteunde SDK: Python, TypeScript, Java, Rust. Iedereen die op de referentie-implementatie bouwde, erfde hem mee.

De cijfers die OX eraan hangt: ruim 7.000 publiek bereikbare servers, pakketten met samen meer dan 150 miljoen downloads, tot 200.000 kwetsbare installaties. Ruim tien CVE's verspreid over namen die je echt draait, LiteLLM, LangChain, LangFlow, Flowise, Windsurf, GPT Researcher, Upsonic, DocsGPT. Dezelfde oorzaak is het afgelopen jaar al los van elkaar gemeld onder andere CVE-nummers, in MCP Inspector, LibreChat, Cursor. Niemand legde het verband totdat iemand ging tellen.

Het pleidooi voor MCP klopt

Ik ga je niet vertellen dat je het eruit moet trekken. Ik gebruik MCP elke dag. Mijn eigen stack steunt erop voor zoeken, databasetoegang en projecttooling. Het protocol loste een echt probleem op: één interface zodat elke agent met elke tool kan praten, in plaats van N maatwerkkoppelingen die op N manieren wegrotten. De adoptie is voorbij de 19.000 servers geschoten en blijft groeien, omdat het werkt.

Juist daarom doet dit ertoe. De schade schaalt mee met het succes.

"Verwacht gedrag"

Hier houdt het op een bugrapport te zijn en wordt het een keuze.

Anthropic keek naar config-to-command execution in elke SDK die ze uitleveren en noemde het verwacht gedrag. Het opschonen van invoer, zeiden ze, is de verantwoordelijkheid van de ontwikkelaar. Een week na de melding pasten ze hun beveiligingsadvies aan met de aanbeveling om STDIO-adapters voorzichtig te gebruiken. Het oordeel van OX over die aanpassing: "Dit heeft niets opgelost."

De zin die in elk AI-team op de muur zou moeten hangen is van hen:

Wat hier een supply chain-gebeurtenis van maakte in plaats van één losse CVE, is dat één architectuurbeslissing, één keer genomen, geruisloos doorsijpelde naar elke taal, elke onderliggende library, en elk project dat erop vertrouwde dat het protocol was wat het leek te zijn.

En het vervolg, het hele npm-drama samengeperst tot twee zinnen:

Verantwoordelijkheid naar de bouwers schuiven verplaatst het risico niet. Het verdoezelt alleen wie het veroorzaakt heeft.

We hebben deze zet eerder gezien. left-pad. event-stream. De overwerkte maintainer die onmogelijk alles kan nakijken wat er onder hem op voortbouwt. Schuif de verantwoordelijkheid naar de randen en niemand is nog eigenaar van het midden. MCP leerde de les niet. Het herhaalde de fout alleen sneller.

Het draaiboek, gericht op je tool-lijst

Typosquatting. Dependency confusion. Kwaadaardige maintainers. Die film kennen we. MCP plakt er een naarder slot aan vast, want wat een agent uit een tool leest is niet alleen code. Het zijn instructies.

Een tool-descriptor is natuurlijke taal die het model in zijn eigen prompt opneemt. Het beschrijvingsveld is een uitvoeringspad. Een naam die één teken afwijkt van de echte server, een verborgen instructie weggemoffeld in de metadata van een tool, een stilletjes aangepast schema, en de agent neemt het ding op in zijn tool-lijst en doet wat er staat. Dit is hetzelfde aanvalsoppervlak waar ik over schreef toen de supportbot van Meta werd overgehaald om wachtwoorden te resetten: een systeem dat niet wantrouwend kán zijn, met een zin voorgeschoteld die op een opdracht lijkt.

OX bleef niet bij de theorie. Ze vergiftigden 9 van de 11 MCP-registries met een proefballon en voerden commando's uit op zes live productieplatformen.

En de servers zelf staan open op manieren die we vijftien jaar geleden hebben opgelost. Eén scan van een paar duizend MCP-servers: 67% met code-injectierisico, 34% command injection, 36,7% kwetsbaar voor SSRF. Dit zijn webbugs uit 2010 die opduiken in AI-infrastructuur van 2026, om de saaiste reden die er is. De mensen die MCP-servers schrijven zijn systeem- en ML-engineers, geen security-engineers, en het protocol gaf ze niets waardoor het veilige pad ook het standaardpad werd.

De supply chain mikt hier al op. Een npm-infostealer ging drie weken geleden recht op de werkmap van Claude af. De agent is het proces op je machine met de meeste rechten dat ook nog eens het meeste vertrouwt, en nu heeft hij ook een pakketbeheerder.

Wat we hier wél dichttimmeren

Je kunt je niet uit een architectuur prompten die config als commandoregel behandelt. Een regel in een prompt is een suggestie. Een harde grens op systeemniveau is echt. Dat is het hele argument voor muren in plaats van beleefdheid, en hier geldt het dubbel.

  • Behandel externe MCP-config als onvertrouwde invoer. Alles wat de JSON-config van een server kan bewerken, kan code draaien. Een config-diff is een code-diff. Die gaat door de review heen, niet eromheen.
  • Zet elke server in een sandbox. Draai MCP-services geïsoleerd, nooit op de machine waar je echte sleutels staan. Dezelfde reflex om de controle terug te pakken die ik ook op mijn eigen server toepaste: ga ervan uit dat het proces vijandig is en stop het in een hok.
  • Blokkeer publieke IP-toegang tot gevoelige diensten. SSRF loont alleen als de server iets kan bereiken dat de moeite waard is. Knip de route door en een derde van die kwetsbaarheden doet er niet meer toe.
  • Pin en verifieer je bronnen. Installeer van bekende, geverifieerde uitgevers, niet van een marktplaats-badge. Reputatie is geen integriteit, de badge kan net zo goed vergiftigd zijn.
  • Houd tool-aanroepen in de gaten. Log wat je agents echt aanroepen. Je betrapt een tool niet op wangedrag als je nooit kijkt wat hij doet.

Weten wat je inplugt

Het lastigere probleem is hetzelfde dat npm tien jaar kostte: hoe zie je het ecosysteem voordat je een stukje ervan vertrouwt?

Om dat gat te dichten heb ik MCP Observatory gebouwd. Het volgt het MCP-ecosysteem zoals je elke registry zou willen volgen die je aan een agent gaat koppelen: releases, dependency-graphs, CVE-feeds, samengestelde risicoscores, en statische analyse die precies de command-injection- en SSRF-patronen markeert die OX overal vond, plus de naam- en imitatietrucs waar typosquatting op draait. Voordat je een server aan je tool-lijst toevoegt, kun je tenminste weten of het een bekend gegeven is of een vreemde die je een zin aanreikt.

npm had tien jaar aan inbraken nodig voordat lockfiles, audittooling en provenance vanzelfsprekend werden. MCP heeft geen tien jaar. Agents krijgen op dit moment shells, credentials en je inbox in handen geduwd, en het protocol eronder levert config-to-command execution en noemt het verwacht gedrag.

We hebben deze les al een keer betaald. We staan op het punt de volle prijs te betalen om hem opnieuw te leren.