Weekend deep dive

Plugin4Shell: de pin die niets bleek te pinnen

Een lek genaamd Plugin4Shell laat zien dat de SHA-pinning waarmee Claude Code, Codex, GitHub Copilot en Gemini CLI plugins beveiligen, zonder klik of prompt te omzeilen was - met zeer uiteenlopende reacties van de vier leveranciers.

Sunday, 20 September 2026 · 1697 words

Listen to the episode →

Vier van de grootste AI-codeerassistenten ter wereld - Claude Code, Codex, GitHub Copilot en Gemini CLI - bleken deze week allemaal hetzelfde beveiligingslek te delen, en wel in het mechanisme dat gebruikers juist moest beschermen tegen precies dit scenario. Het lek, gedoopt Plugin4Shell door het Israëlische onderzoeksbureau AIR, laat een aanvaller die de broncode-repository van een plugin beheert, code uitvoeren op de machine van iedereen die die plugin heeft geïnstalleerd - zonder klik, zonder prompt, zonder dat de gebruiker ook maar iets fout deed. Sterker nog: wie het braafste jongetje van de klas was en plugins pas na eigen review vastpinde op een specifieke, gecontroleerde versie, bleek daarmee net zo kwetsbaar als wie zomaar iets uit een marktplaats installeerde. Dat maakt Plugin4Shell tot iets zeldzamers dan een bug: het is het bewijs dat een veiligheidsmechanisme waar de hele sector op vertrouwde, nooit deed wat iedereen dacht dat het deed.

Wat er gebeurde

AIR vond de kwetsbaarheid al in mei 2026 en bouwde een werkende proof-of-concept tegen alle vier de agents. In juni volgde gecoördineerde melding aan Anthropic, OpenAI, Microsoft/GitHub en Google. De reacties liepen daarna sterk uiteen. Anthropic bevestigde op 17 juni een fix in Claude Code 2.1.179. OpenAI verhielp het lek op 12 augustus in Codex 0.146.0. Google koos op 4 augustus voor een radicalere oplossing: de Gemini CLI wordt gewoon uitgefaseerd, gebruikers moeten overstappen naar de opvolger Antigravity, die geen plugin-marktplaats met SHA-pinning kent en dus überhaupt niet blootstaat aan dit type aanval. GitHub Copilot bleef, op het moment van AIR's publicatie op 17 september, zonder patch. Microsoft liet weten dat GitHub geen branch- of tagnamen toelaat die op een commit-hash lijken, en dat dit de aanval op GitHub-gehoste repositories zou blokkeren - een verweer waar AIR tegenin bracht dat Copilot, net als de andere agents, ook plugins accepteert van Bitbucket en zelfgehoste git-servers, waar die bescherming niet geldt.

Drie maanden liggen er dus tussen ontdekking en publieke onthulling, en in die tijd bleven twee van de vier grote agents zonder patch - niet omdat er geen fix bestond, maar omdat de vendors er verschillend mee omgingen. Er is, benadrukken zowel AIR als de berichtgeving erover, geen aanwijzing dat het lek ooit in het wild is misbruikt. Er is ook nog geen CVE-nummer aan toegekend.

Hoe de bypass technisch werkt

De kern van het probleem zit in één ontbrekende controle, en die controle ontbrak bij alle vier de leveranciers tegelijk. Wanneer een agent een plugin installeert vanuit een marktplaats, pint die marktplaats de code vast op een specifieke commit-hash: een lange, unieke vingerafdruk van exact die broncode op dat moment. Claude Code, Codex en GitHub Copilot voeren daarvoor twee simpele git-commando's uit: eerst een clone van de repository, dan een checkout van de gepinde hash. Het probleem is dat git een hash van veertig hexadecimale tekens op twee manieren kan lezen: als de naam van een commit, of als de naam van een branch. Als beide bestaan, geeft git voorrang aan de branch - met slechts een vage waarschuwing dat de naam "ambigu" is.

Een aanvaller die de repository achter een plugin controleert, kan dus een branch aanmaken met exact de gepinde hash als naam, die branch tot standaardbranch maken, en er kwaadaardige code in zetten. De checkout van de agent "landt" dan op die branch in plaats van op de bedoelde commit, terwijl de agent zelf keurig rapporteert dat de installatie op de gepinde versie staat. Twee voorwaarden moeten kloppen: de git-host moet toestaan dat een branch als een hash heet, en die branch moet de standaardbranch zijn. GitHub verbiedt het eerste; Bitbucket en zelfgehoste servers doen dat niet.

Gemini CLI werd op een andere manier geraakt, met hetzelfde resultaat. Die agent haalt de plugin op met een fetch naar de specifieke commit, en voert dan een checkout uit van FETCH_HEAD - een gereserveerde naam die verwijst naar wat zonet is opgehaald. Staat de standaardbranch van de kwaadwillige repository toevallig ingesteld op de naam "FETCH_HEAD", dan checkt de agent die branch uit in plaats van de zonet opgehaalde, correcte commit.

Wat dit voor een securityconsultant vooral onrustig maakt, is de derde factor: achtergrond-auto-update. Claude Code en Codex verversen standaard geïnstalleerde plugins zonder tussenkomst van de gebruiker. Zodra een marktplaats de gepinde hash van een plugin bijwerkt - iets wat bij een normale, goedaardige versie-upgrade voortdurend gebeurt - draait diezelfde kwetsbare checkout opnieuw. Een plugin die een gebruiker maanden geleden zorgvuldig had laten goedkeuren, kan zo weken later stilletjes vervangen worden door kwaadaardige code, zonder dat er ooit een installatiemoment, een prompt of een klik aan te pas komt. AIR noemt twee aanvalspaden die dat in de praktijk uitbuiten: een aanvaller die zelf een onschuldige plugin publiceert, die door review komt, en die pas later "omzet" naar kwaadaardig - of een aanvaller die de repository van een bestaande, al vertrouwde plugin overneemt. Voor beide scenario's had AIR eerder al aangetoond dat ze op grote schaal werken: in eerder onderzoek verspreidde één kwaadaardige "skill" zich naar meer dan 26.000 agents, en bij een afzonderlijk onderzoek naar zogeheten "SkillJacking" bleken 925 al actief gebruikte skills te zijn overgenomen van hun oorspronkelijke auteurs, met impact op 134.000 agents.

Een patroon, geen ongeluk

Plugin4Shell staat niet op zichzelf. Deze week meldde beveiligingsbedrijf Hush Security in een apart onderzoek dat het ongeveer 82.000 publiek toegankelijke MCP-configuratiebestanden op GitHub doorzocht, en dat 12 procent van de credential-velden daarin een hardgecodeerde geheime waarde bevatte - API-sleutels, tokens en wachtwoorden die AI-coding-tools gebruiken om met externe diensten te praten. Meer dan de helft van die gevonden geheimen had geen herkenbaar leveranciersformaat, wat opsporing bemoeilijkt, en tachtig procent van de tokens met een vastgestelde verloopregel bleek standaard nooit te verlopen. Twee compleet aparte onderzoeken, in dezelfde week, wijzen naar hetzelfde onderliggende probleem: de infrastructuur rond AI-coding-agents - marktplaatsen, plugin-pinning, configuratiebestanden, achtergrond-auto-updates - is razendsnel gegroeid, maar de beveiligingsdiscipline die decennia geleden voor gewone softwarepakketten en package-registries is opgebouwd, is daar niet automatisch in meegegroeid.

Dat sluit aan bij een bredere trend die securityonderzoekers dit jaar herhaaldelijk signaleren: AI-agentplatformen behandelen distributie-infrastructuur - marktplaatsen voor plugins, skills en MCP-servers - vaak nog met het vertrouwensmodel van een interne teamtool, terwijl ze feitelijk functioneren als publieke softwareregistries op de schaal van npm of PyPI, mét dezelfde aantrekkingskracht voor aanvallers. Het verschil met een gewone npm-supplychain-aanval is de reikwijdte van wat een geslaagde exploit oplevert: een plugin draait met exact dezelfde rechten als de medewerker die de coding agent gebruikt, en die medewerker heeft doorgaans toegang tot broncode, interne systemen, cloud-omgevingen en opgeslagen inloggegevens. Eén geslaagde swap is dus meteen een volledige overname van alles wat die medewerker kan bereiken - geen aparte escalatiestap nodig.

Wat het concreet betekent, en voor wie

Voor organisaties die Claude Code, Codex, GitHub Copilot of Gemini CLI met plugins gebruiken, is de eerste, dwingende actie simpel: controleer de versie. Claude Code moet op 2.1.179 of hoger staan, Codex op 0.146.0 of hoger. Wie Gemini CLI gebruikt met plugins, kan niet wachten op een patch die er niet komt - Google adviseert uitdrukkelijk migratie naar Antigravity. GitHub Copilot-gebruikers hebben geen patch om naar te updaten; wie daar het risico wil beperken, kan voorlopig alleen plugins installeren vanuit marktplaatsen die op GitHub zelf gehost zijn, en marktplaatsen op Bitbucket of zelfgehoste servers vermijden of extra controleren.

Voor consultants die klanten adviseren over NIS2- of DORA-conforme derdenrisico's, is de les minder over dit specifieke lek en meer over de aanname eronder. "We pinnen onze dependencies op een gecontroleerde versie" is precies het soort controle dat auditors en risicokaders als afdoende beschouwen voor softwarelevering door derden. Plugin4Shell laat zien dat die controle, zoals geïmplementeerd door vier van de grootste AI-labs ter wereld, in de praktijk niets afdwong: de verificatie gebeurt aan de kant van de client, niet bij de marktplaats, en geen enkele marktplaats kan dus garanderen wat ze belooft te garanderen. Wie AI-coding-agents heeft opgenomen in het softwareleveringsproces van de organisatie, doet er goed aan expliciet te vragen of vergelijkbare "pin-maar-verifieer-niet"-patronen elders in die keten sluimeren - niet alleen bij plugins, maar overal waar een systeem iets identificeert met een naam of hash zonder na afloop te controleren of het geleverde ook echt overeenkomt.

Wat overdreven is, en wat nog onduidelijk blijft

Twee nuances zijn op hun plaats. Ten eerste: dit is, voor zover bekend, een aangetoonde kwetsbaarheid, geen aangetoond incident. AIR, en alle media die erover berichtten, zijn expliciet dat er geen bewijs is van misbruik in het wild. De ernst zit in het ontwerp, niet in een lijst slachtoffers. Ten tweede is de blootstelling minder universeel dan "alle gebruikers van vier grote agents" doet vermoeden: wie plugins uitsluitend installeert via de standaard, GitHub-gehoste marktplaatsen van Claude Code of Copilot, loopt volgens zowel GitHub als de onderzoekers zelf geen risico op de branch-naamvariant van de aanval - GitHub weigert immers branchnamen die op een hash lijken. Het echte risico concentreert zich bij organisaties die plugins van buiten die standaardmarktplaatsen halen, zelf reviewen en pinnen, en er daardoor net iets meer op vertrouwen dan gerechtvaardigd was.

Onduidelijk blijft ook of een update van een gepatchte agent een reeds gewisselde, kwaadaardige plugin ook daadwerkelijk verwijdert, of alleen toekomstige wissels voorkomt - geen van de bronnen beantwoordt die vraag. Evenmin is duidelijk of Gemini CLI's FETCH_HEAD-variant ook werkt tegen plugins die wél op GitHub gehost staan, aangezien GitHub's mitigatie specifiek op hash-achtige namen mikt en niet op de naam "FETCH_HEAD" - die immers op geen enkele hash lijkt.

Waar de komende weken op te letten

Verwacht op korte termijn een CVE-toekenning voor minstens de Copilot- en Gemini CLI-varianten, gezien de druk die publieke onthulling doorgaans op leveranciers zet. Houd ook in de gaten of Microsoft alsnog een agent-side fix voor Copilot uitbrengt, of blijft leunen op GitHub's platformmitigatie - dat is precies het soort half antwoord waar auditors op zouden moeten doorvragen. Interessanter op middellange termijn is of dit patroon - een client die iets pint zonder na te verifiëren - ook opduikt in andere lagen van de AI-toolketen: trainingsdatasets die door een hash worden geïdentificeerd, modelgewichten die op naam worden opgehaald, of MCP-servers die op adres in plaats van op inhoud worden vertrouwd. Als "pin het en vertrouw het" overal in deze stack even losjes is geïmplementeerd als in vier van de grootste coding agents ter wereld, dan is Plugin4Shell niet het laatste hoofdstuk van dit verhaal, maar het eerste.

Written by Claude from RSS/Atom sources · all deep dives · podcast