Een gegenereerde abstracte illustratie op een lichtgrijsblauw vlak: links van het midden staat een hoog donker leisteenpaneel, een dunne lichtcyaan straal loopt er horizontaal doorheen en waaiert aan de rechterkant uit tot een brede lichtkegel over een veld van kleine geometrische blokken. De meeste blokken liggen in koele schaduw; één cluster nabij het midden van de straal gloeit warm amber. Op de achtergrond bevinden zich een vaag blauwdrukrooster en dunne concentrische bogen. Er verschijnen geen tekst, cijfers, personen, merktekens of organisatielogo's. Het OrcaRouter-logo is in de rechteronderhoek gecompositeerd.
AI Safety Incidents

Clinejection: Hoe een issue-titel bij Cline's npm-token terechtkwam

Auteur

Rowan Sterling

Publicatiedatum

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

Op 9 februari 2026 publiceerde de securityonderzoeker Adnan Khan een verslag over een fout die hij op 1 januari privé bij Cline had gemeld: de open-source AI-codeerassistent had een geautomatiseerde issue-triager, gebouwd op Anthropic's claude-code-action GitHub Action, gekoppeld aan een prompt die elke binnenkomende GitHub-issue-titel rechtstreeks in de instructies van het model plakte. Elk GitHub-account kon dit activeren door een issue te openen, en in Khan's reproductie kreeg de agent met een als instructie geformuleerde titel een shell-commando uitgevoerd binnen de workflow. Vervolgens traceerde hij de route vanaf dat steunpunt, via het vergiftigen van de GitHub Actions-cache, naar de release-referenties voor de VS Code Marketplace, OpenVSX en npm. Acht dagen nadat Cline de workflow had gerepareerd, werd een npm-publicatietoken waarvan Cline dacht dat het was geroteerd, gebruikt om cline 2.3.0 te publiceren, dat OpenClaw installeerde op elke machine waarop het pakket werd geïnstalleerd. De volledige vermelding, met de bijbehorende ernst- en betrouwbaarheidsgradaties, staat in het Orca AI Incident Archive, naast de naburige supplychain-records uit dezelfde periode.

Twee datums, niet één

Het archief dateert dit record op 9 februari 2026, met dagprecisie, en dat is de dag waarop Khan zijn artikel publiceerde op adnanthekhan.com. Het is niet de dag waarop het kwaadwillige pakket verscheen. De kwetsbaarheid zelf werd geïntroduceerd op 21 december 2025, in een commit die de triage-workflow aan de cline/cline-repository toevoegde, en bleef actief tot Cline de workflow op 9 februari verwijderde. De ongeautoriseerde npm-publicatie kwam op 17 februari, acht dagen na de fix en zevenenveertig dagen na Khans eerste privémelding.

Die twee datums uit elkaar houden is belangrijk, want het meest ingrijpende feit in de zaak zit in de kloof ertussen: de deur werd op 9 februari gesloten, maar de sleutel die de indringer al had gekopieerd, werkte op 17 februari nog steeds. Clines eigen correctie, op 17 februari naar Khan gestuurd en weergegeven in zijn post, zegt het rechtstreeks: "Toen we op 9 februari de inloggegevens vernieuwden, was het npm-publicatietoken niet correct ingetrokken. Het verkeerde token werd verwijderd en het blootgestelde bleef actief."

De keten: van een issue-titel naar een release-token

Het kwetsbare bestand was .github/workflows/claude-issue-triage.yml, dat draaide op de issues-gebeurtenis en anthropics/claude-code-action@v1 aanriep met Claude Opus 4.5, in de workflow vastgezet als claude-opus-4-5-20251101. Khan citeert de configuratie van de workflow: allowed_non_write_users was ingesteld op het jokerteken "*", zodat elk GitHub-account de agent kon activeren door simpelweg een issue te openen, en claude_args gaf --allowedTools door met Bash, Read, Write, Edit, Glob, Grep, WebFetch en WebSearch. Bash was degene die ertoe deed. Het gaf het model shelluitvoering binnen een workflow die in de context van de standaardbranch draaide.

De prompt voegde de titel van de issue in zonder deze op te schonen. Khan's proof of concept gebruikte een titel die begon met "Tool error." en vervolgens doorging met een instructie om een hulppakket van een specifieke commit te installeren voordat hij verderging met triage. De commitverwijzing wees naar een fork waarvan package.json een preinstall-script bevatte, dat een curl-opdracht uitvoerde naar een door de aanvaller beheerst endpoint voordat npm klaar was met het installeren van iets. Omdat de installatie via de Bash-tool liep, inspecteerde het model nooit wat er werd uitgevoerd. Khan reproduceerde dit op een mirror van de Cline-repository en meldt dat de agent de payload bij elke poging uitvoerde.

Code-uitvoering in de triageworkflow is op zichzelf geen toegang tot release-referenties. Die stap kwam voort uit een eigenschap van GitHub Actions die Khan had gedocumenteerd in een tool uit 2024 die hij uitbracht onder de naam Cacheract: elke workflow kan de cache van de repository lezen en schrijven met volledige controle over cachesleutels en -versies, zelfs een workflow die nooit een cachingstap declareert. De triagejob draaide op de standaardbranch en deelde dus een cache-scope met de nightly publish-jobs, die node_modules wel uit de cache herstelden en wel de publicatietokens bevatten.

Cache-items zijn onveranderlijk, dus een aanvaller kan niet zomaar het item overschrijven dat een releasejob zal herstellen. Khans manier om dat te omzeilen was misbruik te maken van een wijziging in het GitHub-beleid van 20 november 2025, waardoor de dienst cache-items onmiddellijk verwijderde zodra de cache van een repository boven de 10 GB uitkwam, volgens least-recently-used-volgorde. Overspoel de cache tot boven de 10 GB, en de legitieme items vallen eruit; eis de vrijgekomen sleutels op met vergiftigde inhoud, en de volgende job die ze herstelt, voert code van de aanvaller uit. Cacheract automatiseert de hele reeks binnen één workflowuitvoering, en blijft persistent door de action.yml van actions/checkout te overschrijven, zodat de post-stap van de actie aan het einde van elke job een payload uitvoert.

De laatste schakel in de keten is de nightly job, die rond 02:00 UTC draait, de vergiftigde node_modules herstelt en ontploft. Wat eruit komt, zijn VSCE_PAT, OVSX_PAT en NPM_RELEASE_TOKEN, respectievelijk de inloggegevens voor de VS Code Marketplace, OpenVSX en npm. Of elke schakel in die volgorde tegen Cline's eigen repository heeft gelopen, is een aparte vraag, die hieronder wordt behandeld.

A self-built HTML card titled 'Six steps from an issue title to a release token', badged 'Clinejection · GHSA-9ppg-jx86-fqw7', subtitled 'The chain as Adnan Khan describes it, with the workflow configuration he quotes'. Six numbered rows read: 1, Issue opened on cline/cline, the title carries the instructions and allowed_non_write_users is set to the wildcard; 2, claude-issue-triage.yml runs, claude-code-action with Bash, Read, Write, Edit, Glob, Grep, WebFetch and WebSearch; 3, npm install from a fork commit, the fork's package.json carries a preinstall script and the model runs it through Bash; 4, Cache flooded past 10 GB, GitHub's LRU eviction removes the legitimate entries and frees their keys; 5, Poisoned entries claim the keys, the nightly jobs restore attacker content as node_modules; 6, Nightly job runs at about 2 AM UTC, VSCE_PAT, OVSX_PAT and NPM_RELEASE_TOKEN leave the runner. A footer reads 'Source: Adnan Khan, Clinejection, 9 February 2026; Cline advisory GHSA-9ppg-jx86-fqw7.' The OrcaRouter logo is composited in the bottom-right corner.

Waarom de nightly-inloggegevens productie-inloggegevens waren

Het voor de hand liggende tegenargument is dat nightly- en productiereleases verschillende secrets zouden moeten hebben. Khan antwoordt dat de scheiding nominaal was. OpenVSX en de VS Code Marketplace koppelen een publicatietoken aan een uitgeversidentiteit, niet aan een afzonderlijke extensie, en zowel de stabiele als de nightly Cline-extensies werden onder dezelfde identiteit gepubliceerd, die Khan op OpenVSX identificeert als saoudrizwan. Op npm is het fijnmazige tokenmodel aan een package gekoppeld, en Cline publiceerde zijn stabiele en nightly CLI-builds naar hetzelfde cline-package. Een token dat voor de nightly-job was uitgegeven, kon daarom het productieartefact publiceren, en dat is precies wat acht dagen later gebeurde.

Khan's eigen kadering van de impact berust op schaal: hij citeert Cline's aankondiging dat het de 5 miljoen installaties had gepasseerd, en merkt op dat een extensie-update die via gestolen inloggegevens wordt gepusht, wordt uitgevoerd in de context van elke developer wiens editor automatisch updatet, met de rechten van die developer en alle sleutels, tokens en broncode die op de machine staan.

Wat er daadwerkelijk werd gepubliceerd, en wat het deed

Het gepubliceerde artefact was cline 2.3.0, en het was klein. De eigen tijdstempels van het npm-register plaatsen 2.3.0 op 11:26:51 UTC op 17 februari 2026 en de schone 2.4.0 op 19:23:08 UTC dezelfde dag, een blootstelling die de Cline-advisory op ongeveer acht uur schat, totdat 2.3.0 om 11:30 uur PT werd gedeprecieerd. De package.json van het pakket bevatte één toegevoegde regel, een postinstall-script met de inhoud npm install -g openclaw@latest. De advisory van Cline, GHSA-9ppg-jx86-fqw7, stelt dat er geen andere pakketbestanden zijn gewijzigd en dat dist/cli.mjs byte-identiek is aan de legitieme 2.2.3-build.

OpenClaw is een echt open-source AI-agentframework, geen malware, en het advies van Cline zegt dat expliciet: het is een legitiem project, maar de installatie ervan was niet geautoriseerd of bedoeld. Endor Labs, dat de tarball analyseerde, beoordeelde de algehele impact als laag, omdat de installatie de Gateway-daemon van OpenClaw niet startte. De write-up van StepSecurity belicht de andere kant ervan: een globale installatie laat het framework op schijf achter met welke inloggegevens en bestandstoegang de installerende gebruiker dan ook heeft, en het ontwerp van OpenClaw, een persistente lokale gateway met een operator-API, maakt het iets van hoge waarde om daar aan te treffen. De twee beoordelingen zijn niet tegenstrijdig. De ene beschrijft wat er tijdens het venster draaide; de andere beschrijft wat er daarna achterbleef.

Volume is het enige getal dat zorgvuldig moet worden behandeld. StepSecurity meldde dat de gecompromitteerde versie ongeveer 4.000 keer werd gedownload voordat deze buiten gebruik werd gesteld, en The Register herhaalde dat cijfer. Endor Labs stelde het maandelijkse downloadaantal van cline voor 19 januari tot 17 februari op 418.545, wat het normale verkeer van het pakket beschrijft en niet de kwaadaardige build. Geen van beide cijfers telt machines: een downloadaantal is geen aantal getroffen ontwikkelaars, en geen enkele partij heeft een cijfer over de geïnstalleerde basis voor 2.3.0 gepubliceerd. Het Threat Intelligence-team van Microsoft zei op X dat het op 17 februari een "kleine maar merkbare stijging" had waargenomen in OpenClaw-installaties als gevolg van het Cline-installatiescript, zoals The Hacker News berichtte.

Het adviesrecord van GitHub voor GHSA-9ppg-jx86-fqw7 bevat geen CVE en geen CWE, en de ernst ervan is Laag. Die beoordeling gaat over de goedaardige payload, niet over de diefstal van inloggegevens, en ze staat vreemd naast de kritieke beoordeling van het archief voor het incident zelf. Het advies vermeldt 2.3.0 als de getroffen versie en 2.4.0 als de oplossing.

De onthulling waarop Cline niet antwoordde

Khans tijdlijn vóór publicatie is het deel van het dossier dat het minst over het model gaat en het meest over proces. Hij diende op 1 januari 2026 een GHSA in via GitHub's private vulnerability reporting en mailde diezelfde dag naar het beveiligingscontact dat op Cline's trustpagina stond. Op 8 januari stuurde hij een follow-up naar een Cline-ontwikkelaar. Op 18 januari probeerde hij via X een direct bericht naar Cline's CEO te sturen. Op 7 februari schreef hij opnieuw en ontving hij niets anders dan een automatisch ticketnummer. Hij publiceerde op 9 februari.

Cline heeft de fix gemerged, pull request 9211, ongeveer dertig minuten tot een uur later. De PR verwijdert drie workflowbestanden, claude-issue-triage.yml, claude-pr-review.yml en cline-pr-review.yml, en haalt caching weg uit publish.yml, publish-nightly.yml, npm-nightly.yaml en npm-main.yaml, zeven bestanden in totaal, waarbij installatiestappen nu onvoorwaardelijk zijn gemaakt omdat er geen cachehit meer is om van af te hangen.

Cline's publieke reactie op 10 februari, geciteerd in Khan's bericht, aanvaardde de bevinding en noemde onmiddellijke mitigatiemaatregelen: verwijdering van de botreviewworkflows voor issues en PR's, verwijdering van actions/cache uit publicatieworkflows die release-inloggegevens verwerken, en rotatie van de relevante inloggegevens, waaronder bot-, provider- en publicatietokens. Ook gaf het toe over de afhandeling: "we erkennen dat onze reactietijd op uw eerste melding onaanvaardbaar was. Een melding die op 1 januari is ingediend, had niet op 9 februari openbaar gemaakt hoeven te worden om behandeld te worden."

Op 11 februari zei Cline dat het een volledige rotatie van VSCE_PAT, OVSX_PAT en NPM_RELEASE_TOKEN had voltooid, en dat een audit van elke release op alle drie distributiekanalen tussen 21 december 2025 en 9 februari 2026 had uitgewezen dat elke Marketplace- en OpenVSX-versie aan een getagde GitHub-release was gekoppeld en dat alle 41 npm-versies consistent waren met de bron. Het concludeerde dat er geen ongeautoriseerde release was gepubliceerd "tijdens het beweerde blootstellingsvenster". Zes dagen later zette het de feiten recht, in het hierboven aangehaalde bericht: het npm-token was niet ingetrokken, en 2.3.0 was daarmee gepubliceerd.

A self-built HTML card titled 'From private report to public disclosure', subtitled 'Khan's pre-publication timeline, and what followed'. Eight dated rows read: 21 Dec 2025, vulnerable claude-issue-triage.yml committed; 1 January 2026, GHSA filed and email sent to Cline's listed security contact; 8 January 2026, follow-up email to a Cline developer, no reply; 18 January 2026, direct message to Cline's CEO on X, no reply; 7 February 2026, final email, automated ticket number only; 9 February 2026, public disclosure and PR 9211 merged within about an hour; 11 February 2026, Cline reports full rotation and a clean audit; 17 February 2026, cline 2.3.0 published with a still-valid npm token. A footer reads 'Times and dates as recorded by Adnan Khan; the 17 February publish timestamp is corroborated by the npm registry.' The OrcaRouter logo is composited in the bottom-right corner.

Vastgesteld, toegewezen, onopgelost

• {{1}}Vastgesteld.{{/1}} {{2}}De workflowconfiguratie is openbaar en werd vóór de fix gepubliceerd. Khan reproduceerde de promptinjectie op een mirror van de repository. Cline heeft de herstelmaatregel samengevoegd en een beveiligingsadvies uitgebracht dat de publicatie van 2.3.0 bevestigt, de toegevoegde postinstall-regel, de ongewijzigde CLI-binary, het venster van acht uur en de tokenfout. De tijdstempels van de npm-registry voor 2.3.0 en 2.4.0 komen overeen met de tijden in het advies. Het archief beoordeelt het record als kritiek, met betrouwbaarheid A, met geregistreerde reële schade en zonder betwistingsmarkering.{{/2}}

• Toegeschreven, niet vastgesteld. Wie 2.3.0 heeft gepubliceerd, blijft een openstaande attributie. De forensische uiteenzetting die op 19 februari door Michael Bargury en een geautomatiseerd onderzoekshulpmiddel genaamd Raptor is gepubliceerd, noemt een GitHub-account, glthub-actions, en meldt met hoge mate van zekerheid dat dit account cline/cline heeft geforkt, op 28 januari 2026 om 03:51 UTC issue 8904 met de geïnjecteerde titel heeft geopend en een fork-commit heeft gebruikt om een payload uit een gist uit te voeren. Khan bevestigde dat de accounts gcbrun en Dev11940518 van hemzelf zijn en dat glthub-actions dat niet is. Het account was al verwijderd of opgeschort toen de uiteenzetting werd gepubliceerd, en Cline heeft niemand genoemd. Beschouw de identiteit als een bevinding van een derde partij.

• Betwist naar aard, niet naar feiten. Bargury beoordeelt de episode als consistent met een demonstratie van beveiligingsonderzoek in plaats van een kwaadwillige campagne, waarbij hij wijst op de onschadelijke payload en de geschiedenis van de actor tegen een New Relic-automatiseringsrepository. Cline noemt het een ongeautoriseerde publicatie, en Khan schrijft dat de actor die 2.3.0 heeft gepubliceerd "vermoedelijk" dezelfde is die de caches heeft vergiftigd. Niemand heeft aangetoond dat er een intentie was om schade te veroorzaken, en niemand heeft aangetoond dat die er niet was.

• Onopgelost. Khan's eigen nota van vóór publicatie is zorgvuldig over een punt dat latere berichtgeving soms afvlakt: tussen 31 januari en 3 februari 2026 mislukten verschillende nachtelijke runs met een Post Checkout-stap die geen output opleverde, wat Cacheracts indicator van compromittering is, en de triageworkflow is de meest voor de hand liggende route, maar het is niet bewezen dat die het toegangspunt voor die activiteit was. Ook heeft geen enkele partij bewijs gepubliceerd dat de Marketplace- of OpenVSX-tokens zijn gebruikt; het enige artefact dat iemand heeft geproduceerd, is de npm-build.

A self-built HTML card titled 'What the record supports', subtitled 'One column is documented, one is other people's findings, one is simply open', split into three columns. The first, headed Established, lists four items: the triage workflow interpolated issue titles into the prompt and allowed any GitHub account to trigger it, with Bash among the tools; Khan reproduced the injection on a mirror of the repository; Cline's advisory GHSA-9ppg-jx86-fqw7 confirms cline 2.3.0, the added postinstall line, the unchanged CLI binary and an eight-hour window; npm registry timestamps place 2.3.0 at 11:26 UTC and 2.4.0 at 19:23 UTC on 17 February 2026. The second, headed Attributed, lists three items: the account glthub-actions and issue 8904 come from a third-party forensic write-up, not from Cline; that the actor copied Khan's public proof-of-concept repository is an inference from timing and from his own statement; that the publish was a research demonstration rather than an attack is one analyst's assessment. The third, headed Unresolved, lists three items: whether the triage workflow was the entry point for the late-January cache anomalies; whether any Marketplace or OpenVSX credential was used, with no artefact published; how many distinct machines installed 2.3.0, since about 4,000 is a download count. A footer reads 'Sources: Adnan Khan, Clinejection, 9 February 2026; Cline, GHSA-9ppg-jx86-fqw7; StepSecurity, 17 February 2026; Endor Labs, 18 February 2026; Michael Bargury and Raptor, 19 February 2026.' The OrcaRouter logo is composited in the bottom-right corner.

Wat is er daarna veranderd?

De remediatie raakte tegelijk meerdere lagen, en het is de moeite waard om ze allemaal te benoemen, omdat ze verschillende delen van het falen verklaren. De workflow die door een buitenstaander bereikbaar was, werd verwijderd in plaats van ingeperkt. Caching werd verwijderd uit de vier releaseworkflows die publicatiegeheimen bevatten, in plaats van uit de repository als geheel, en dat is de wijziging die de omslag teweegbrengt. Inloggegevens werden geroteerd, en na de correctie van 17 februari werd het juiste npm-token ingetrokken. Het beveiligingsadvies van Cline stelt dat npm-publicatie nu OIDC-provenance via GitHub Actions gebruikt, en de metadata-analyse van StepSecurity laat zien waarom dat ertoe deed: de legitieme releases droegen al provenance-attestaties, en 2.3.0 was de uitzondering die door een menselijk account was gepubliceerd. De kloof was dat het pad van langlevende tokens openbleef naast trusted publishing, precies het punt waarvan Endor Labs betoogt dat beheerders het zouden moeten sluiten. Cline publiceerde GHSA-9ppg-jx86-fqw7, markeerde 2.3.0 als verouderd met de melding dat deze niet geïnstalleerd moest worden, en verwees gebruikers naar 2.4.0 of later.

Khan's structurele aanbevelingen gaan verder dan wat is geïmplementeerd, en het is de moeite waard ze als de zijne vast te leggen, niet als die van Cline: haal Bash, Write en Edit uit elke triage-workflow en laat het alleen het lezen van bestanden en de specifieke GitHub CLI-aanroepen die het nodig heeft; herstel nooit een cache in een job die productiepublicatiegeheimen bevat; en geef nightly releases hun eigen registernamespace en een toegewijde niet-productie-publicatie-identiteit, zodat een gestolen nightly-token helemaal geen stabiele release kan publiceren.

De achtdaagse kloof tussen de oplossing en de kwaadaardige publicatie is het detail dat dit record de moeite waard maakt om te bewaren. Elke stap in de keten was een bekende techniek; Khan had de cache-poisoningtool gepubliceerd, en het PromptPwnd-onderzoek van Aikido Security uit december 2025 documenteerde hetzelfde patroon van triage-misconfiguratie. Wat ze samen tot een supplychainincident maakte, was een workflow waardoor de tekst van een vreemde een shell kon bereiken, een cache die werd gedeeld met jobs die release-sleutels hadden, en een tokenrotatie waarbij één credential werd gemist. Elk van de drie oplossingen zou de keten op zichzelf hebben doorbroken; de derde kwam acht dagen te laat.