Safeguard
Software Supply Chain Security

Clinejection: prompt injection turns AI coding bot into supply chain attack

A prompt-injected GitHub issue title hijacked Cline's AI triage bot, poisoned its build cache, and pushed a malicious npm release to 4,000 developers.

Nayan Dey
Security Researcher
7 min read

On February 17, 2026, at 3:26 AM PT, an unauthorized actor published cline@2.3.0 to the npm registry, quietly adding a postinstall script that force-installed a separate AI agent package, OpenClaw, on every machine that ran npm install. Roughly 4,000 developers pulled the poisoned package before Cline's maintainers deprecated it about eight hours later, at 11:30 AM PT. The token used to publish it had been stolen through a vulnerability chain that security researcher Adnan Khan had publicly disclosed just eight days earlier and dubbed "Clinejection" — because the exploit worked by prompt-injecting Cline's own AI-powered GitHub issue triage bot. A single issue title, postable by any GitHub account, could trick the bot into running attacker-controlled code with shell access on Cline's CI runners. From there, GitHub Actions cache poisoning turned that foothold into stolen publishing credentials for the VS Code Marketplace, OpenVSX, and npm. Here's how the chain worked, and what it means for anyone running AI agents in CI.

What is Clinejection?

Clinejection is the name Adnan Khan gave to a vulnerability chain in Cline — an open-source AI coding agent with roughly 90,000 weekly npm downloads for its CLI — that let any GitHub user hijack Cline's production release pipeline just by opening an issue. Cline had added an AI-powered "Claude Issue Triage" GitHub Actions workflow in December 2025, built on Anthropic's claude-code-action, and configured it with allowed_non_write_users: "*" plus broad tool access (Bash, Read, Write, Edit). That combination meant the triage bot would act on instructions from anyone who could open a GitHub issue, and it had a shell to do it with. Khan researched the flaw between December 21, 2025 and February 9, 2026, then disclosed it publicly after repeated attempts to reach the Cline team privately went unanswered, by his own account. Cline fixed the workflow only after the public write-up — pulling the AI triage workflows and stripping cache usage from publish jobs within roughly 30 minutes of Khan's post going live. That fast patch closed the injection vector itself, but it did not undo whatever had already been exfiltrated while the flaw was live, which is exactly what came back to bite the project eight days later.

How did a single GitHub issue title compromise Cline's release pipeline?

It worked because the issue title itself was the attack payload. Cline's triage workflow took the raw issue title and interpolated it directly into the prompt it handed to Claude, with no sanitization step in between. An attacker opened an issue with a title written to look like an ordinary performance bug report, but phrased so that when the triage bot read it as an instruction, it complied: run npm install against a commit hosted on an attacker-controlled fork. The attacker had pushed a malicious commit to that fork and then deleted the fork — but GitHub's shared object storage kept the commit reachable, so the install still pulled it down. The installed package's install script deployed Cacheract, a GitHub Actions cache-poisoning tool Khan originally published in December 2024, directly onto the triage workflow's runner. From there, the exploit pivoted out of the sandboxed triage job and into Cline's separate nightly release workflows, which is where the real damage began.

What is GitHub Actions cache poisoning, and why did it work here?

Cache poisoning worked because Cline's triage workflow and its nightly publish workflow shared the same GitHub Actions cache scope. Cacheract floods the cache with more than 10 GB of junk data, forcing GitHub's cache to evict older entries once it hits its size limit, then immediately re-registers the freed cache keys with attacker-controlled content matching the keys the nightly workflow expects to restore. When "Publish Nightly Release" and "Publish NPM Nightly" ran at roughly 2:00 AM UTC, they restored the poisoned cache instead of a clean one, executing the attacker's code with access to three long-lived secrets: VSCE_PAT (VS Code Marketplace), OVSX_PAT (OpenVSX), and NPM_RELEASE_TOKEN. All three were exfiltrated. No scoped-token boundary or credential isolation separated the triage job's blast radius from the release job's secrets, so a comment-triggered bot with shell access ended up one cache write away from three publishing keys.

What happened when attackers actually exploited the flaw?

Eight days after Khan's disclosure, someone used the stolen NPM_RELEASE_TOKEN to publish an unauthorized cline@2.3.0 to npm. The published package.json added a single line — "postinstall": "npm install -g openclaw@latest" — while the CLI binary and every other file stayed byte-for-byte identical to the legitimate cline@2.2.3 release. OpenClaw is not itself malware, but its install was neither reviewed nor authorized, and the mechanism proved that arbitrary code execution was available to whoever held the token. The package was live from 3:26 AM to roughly 11:30 AM PT on February 17, 2026 — about eight hours — during which around 4,000 installs pulled it down. Cline shipped a corrected 2.4.0 at 11:23 AM PT, deprecated 2.3.0 seven minutes later, revoked the compromised token, and moved npm publishing to OIDC-based trusted publishing so no long-lived npm token exists to steal going forward. GitHub tracked the incident as GHSA-9ppg-jx86-fqw7 and rated it "Low" severity under standard scoring — a rating that undersells an exploit chain that achieved unauthorized code execution on thousands of developer machines through a fully automated pipeline. In the weeks after, Cline also committed to removing GitHub Actions cache from any workflow that touches credentials, adding verification requirements around credential rotation, publishing a vulnerability disclosure process with defined response SLAs, and commissioning a third-party audit of its CI/CD infrastructure.

Why does Clinejection matter for teams beyond Cline?

Clinejection matters because it proves an AI coding agent's threat model has to treat its own prompt inputs as an attack surface, not just the code it writes. Every ingredient here was already understood on its own — indirect prompt injection, GitHub Actions cache poisoning (Khan had demonstrated Cacheract against Angular's build infrastructure back in December 2024), and shared long-lived CI secrets — but composing them required no privileged access, no zero-day, and no social engineering beyond a plausible-sounding bug title. Any project that lets an LLM-driven bot read untrusted text — issue titles, PR descriptions, commit messages, even code comments — and act on it with shell, network, or cache access inside the same trust boundary as its release credentials carries the same shape of exposure, whether the agent is Cline, a custom GitHub Action, or an internal support bot wired into CI/CD.

How Safeguard Helps

Safeguard is built for exactly this failure mode: supply chain compromises that slip in through legitimate, signed releases rather than obviously malicious packages. Safeguard's reachability analysis would flag that an injected postinstall script actually executes in production installs, instead of burying the finding in a "Low" severity advisory alongside thousands of unreachable results. Griffin AI, Safeguard's investigation engine, correlates anomalous CI behavior — an npm publish outside a known release commit, or a workflow restoring cache entries it never wrote — against the SBOM Safeguard generates, or ingests from your existing CycloneDX/SPDX pipeline, so a package like cline@2.3.0 gets flagged the moment its published artifact diverges from its source repository. When a compromised or unauthorized version does land, Safeguard's auto-fix PRs pin the last known-good release and open a reviewable diff automatically, shrinking the multi-hour exposure window Cline's team spent manually detecting, deprecating, and re-publishing. The goal is to catch a trusted pipeline the moment it starts behaving like an untrusted one — before 4,000 installs happen, not after.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.