一幅生成的抽象插圖,背景為淺灰藍色:一塊高聳的深石板色面板位於中央偏左,一道纖細的淡青色光束水平穿過它,並在右側展開成一道寬廣的光錐,橫跨一片由小型幾何方塊構成的區域。多數方塊處於冷色陰影中;靠近光束中心的一簇方塊則散發溫暖的琥珀色光芒。背景隱約可見藍圖網格與細緻的同心弧線。圖中沒有出現任何文字、數字、人物、品牌標誌或組織標誌。OrcaRouter 標誌合成於右下角。
AI Safety Incidents

Clinejection:一個 Issue 標題如何觸及 Cline 的 npm Token

作者

Rowan Sterling

發佈日期

最新模型 · 20查看全部模型 →
基準測試:Artificial Analysis · 每日更新
返回全部文章

2026 年 2 月 9 日,安全研究員 Adnan Khan 發表了一篇記述,說明他於 1 月 1 日私下向 Cline 回報的漏洞:這個開源 AI 程式設計助理將一個以 Anthropic 的 claude-code-action GitHub Action 建構的自動化問題分診器,串接到一段提示詞,而該提示詞會把任何送進來的 GitHub issue 標題直接貼進模型的指示中。任何 GitHub 帳號只要開啟一個 issue 就能觸發它;在 Khan 的重現中,一個以指令語氣撰寫的標題讓該代理在工作流程內執行了一段 shell 命令。他接著追溯了從那個立足點出發,經由 GitHub Actions 快取投毒,一路通往 VS Code Marketplace、OpenVSX 與 npm 發佈憑證的路徑。在 Cline 修復該工作流程的八天後,一個 Cline 以為已經輪替過的 npm 發佈權杖被用來發佈 cline 2.3.0,而這個套件會在每一台安裝它的機器上安裝 OpenClaw。完整條目連同其嚴重性與信心等級,收錄於Orca AI Incident Archive,與同一時期鄰近的供應鏈紀錄並列。

兩個日期,不是一個

檔案將這筆紀錄的日期定為 2026 年 2 月 9 日,精確度為日;而那天正是 Khan 在 adnanthekhan.com 發表其文章的日期。這不是惡意套件出現的日期。該漏洞本身是在 2025 年 12 月 21 日引入,出現在一個將分流工作流程加入 cline/cline 儲存庫的提交中,並一直保持生效,直到 Cline 在 2 月 9 日刪除該工作流程。未經授權的 npm 發布則發生在 2 月 17 日,即修正後八天、Khan 首次私下通報後四十七天。

把這兩個日期分開來看很重要,因為本案中最具關鍵性的事實,正好落在兩者之間的空檔:門在2月9日就已經關上,但入侵者早已複製的那把鑰匙,在2月17日依然管用。Cline 本人的更正說得很直白——那份更正於2月17日發給 Khan,並轉載於他的文章中:「我們在2月9日輪換憑證時,npm 發布權杖並未被妥善撤銷。被刪除的是錯誤的權杖,而外洩的那一個仍然有效。」

這條鏈:從議題標題到發佈權杖

有漏洞的檔案是 .github/workflows/claude-issue-triage.yml,它會在 issues 事件上執行,並以 Claude Opus 4.5 叫用 anthropics/claude-code-action@v1,該模型在工作流程中固定為 claude-opus-4-5-20251101。Khan 引述該工作流程的設定:allowed_non_write_users 被設為萬用字元 "*",因此任何 GitHub 帳號只要開啟一個 issue 就能觸發該代理程式;而 claude_args 傳入 --allowedTools,包含 Bash、Read、Write、Edit、Glob、Grep、WebFetch 與 WebSearch。真正關鍵的是 Bash。它讓模型在一個於預設分支情境中執行的工作流程內取得 shell 執行權。

提示詞在未經清理的情況下插入了問題標題。Khan 的概念驗證使用了一個開頭為「Tool error.」的標題,後面接著一項指示:先從特定提交安裝輔助套件,再繼續進行分類處理。該提交參照指向一個 fork,其 package.json 帶有 preinstall 指令碼,該指令碼在 npm 完成任何安裝之前,就對攻擊者控制的端點執行 curl 命令。由於安裝是透過 Bash 工具執行,模型從未檢查實際執行了什麼。Khan 在 Cline 儲存庫的鏡像上重現了此問題,並回報該代理程式在每次嘗試中都執行了酬載。

分類工作流程中的程式碼執行本身,並不代表就能取得發佈憑證。那一步來自 GitHub Actions 的一項特性,Khan 在他 2024 年發布、名為 Cacheract 的工具中記錄了這一點:任何工作流程都能讀寫儲存庫的快取,並完全控制快取鍵與版本,即使是從未宣告快取步驟的工作流程也一樣。分類工作是在預設分支上執行,因此與夜間發佈工作共用快取範圍;而那些夜間發佈工作確實會從快取還原 node_modules,且確實持有發佈權杖。

快取項目不可變,因此攻擊者無法直接覆寫發布作業將還原的快取項目。Khan 的繞道方式是利用 GitHub 於 2025 年 11 月 20 日的政策變更:一旦儲存庫的快取超過 10 GB,該服務便會依最近最少使用順序立即驅逐快取項目。把快取灌爆超過 10 GB,合法項目就會因老化而被淘汰;再以遭汙染的內容佔用空出的鍵,下一個還原這些項目的作業就會執行攻擊者的程式碼。Cacheract 會在單一工作流程執行內自動化整個流程,並透過覆寫 actions/checkout 的 action.yml 來持續潛伏,使該動作的 post 步驟在每個作業結束時執行酬載。

鏈條上的最後一環是夜間作業,它約在 UTC 凌晨 2 點執行,還原被投毒的 node_modules,然後引爆。最終流出的是 VSCE_PAT、OVSX_PAT 與 NPM_RELEASE_TOKEN,分別是 VS Code Marketplace、OpenVSX 與 npm 的憑證。至於每個環節是否都按該順序在 Cline 自己的儲存庫上執行,則是另一個問題,將於下文討論。

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.

為什麼夜間排程所用的憑證會是正式環境的憑證

顯而易見的反對意見是,夜間版與正式版發布應該持有不同的密鑰。Khan 的回答是,這種分離只是名義上的。OpenVSX 與 VS Code Marketplace 將發布權杖綁定到發佈者身分,而不是個別擴充功能;而 Cline 的穩定版與夜間版擴充功能都是在同一個身分下發布,Khan 在 OpenVSX 上指認該身分為 saoudrizwan。在 npm 上,精細權杖模型綁定到套件,而 Cline 將其穩定版與夜間版 CLI 建置發布到同一個 cline 套件。因此,為夜間作業簽發的權杖可以發布正式產物,而這正是八天後發生的事。

Khan 自己對這起影響的定調,關鍵在於規模:他引用 Cline 宣布安裝數已突破 500 萬次,並指出,透過遭竊憑證推送的擴充功能更新,會在每一位編輯器設定為自動更新的開發者環境中執行,並具備該開發者的權限,以及機器上任何金鑰、權杖與原始碼。

實際發表了什麼,以及它做了什麼

已發佈的產物是 cline 2.3.0,而且體積很小。npm registry 自身的時間戳顯示,2.3.0 於 2026 年 2 月 17 日 11:26:51 UTC 發佈,而乾淨的 2.4.0 於同日 19:23:08 UTC 發佈;Cline 公告估計暴露時間約為八小時,直到 2.3.0 於太平洋時間上午 11:30 被棄用。該套件的 package.json 多了一行,即一個內容為 npm install -g openclaw@latest 的 postinstall 指令碼。Cline 的公告 GHSA-9ppg-jx86-fqw7 指出,沒有其他套件檔案遭到變更,且 dist/cli.mjs 與合法的 2.2.3 建置版本位元組完全相同。

OpenClaw 是真正開源的 AI 代理框架,並非惡意軟體,而 Cline 的公告也明確如此表示:它是合法專案,但其安裝未經授權,也非預期。分析該 tarball 的 Endor Labs 將整體影響評估為低,理由是安裝過程並未啟動 OpenClaw 的 Gateway 守護程式。StepSecurity 的報告則從另一面衡量:全域安裝會把該框架留在磁碟上,並帶著安裝使用者所擁有的任何憑證與檔案存取權;而 OpenClaw 的設計——一個具備操作者 API 的常駐本機閘道——使其成為在那裡被發現時價值極高的目標。這兩份評估並不矛盾。一份描述的是在該時間窗口內執行了什麼;另一份描述的是之後留下了什麼。

下載量是唯一必須謹慎處理的數字。StepSecurity 報告指出,遭入侵的版本在被棄用前約被下載 4,000 次,The Register 也重複引用了這個數字。Endor Labs 將 cline 在 1 月 19 日至 2 月 17 日的月度下載量列為 418,545,這反映的是該套件的正常流量,而非惡意建置版本。這兩個數字都不是機器數量:下載次數不等於受影響開發者人數,且沒有任何一方公布 2.3.0 的安裝基數。Microsoft 的 Threat Intelligence 團隊在 X 上表示,他們在 2 月 17 日觀察到 OpenClaw 安裝數出現「小幅但明顯的上升」,這是源自 Cline 安裝指令碼,正如 The Hacker News 所報導。

GitHub 對 {{1}}GHSA-9ppg-jx86-fqw7{{/1}} 的公告記錄未包含 {{2}}CVE{{/2}},也未包含 {{3}}CWE{{/3}},其嚴重性為 {{4}}低{{/4}}。該評級是針對{{5}}無害的酬載{{/5}},而非針對憑證竊取,且與檔案庫對該事件本身所給的{{6}}嚴重等級{{/6}}並列時顯得突兀。該公告記錄 {{7}}2.3.0{{/7}} 為受影響版本,{{8}}2.4.0{{/8}} 為修正版本。

Cline 未回應的披露

Khan 的公布前時間軸,是紀錄中最不涉及模型、而最關乎流程的部分。他於 2026 年 1 月 1 日透過 GitHub 的私人漏洞通報提交了一份 GHSA,並在同日寄電子郵件給 Cline 信任頁面上所列的安全聯絡人。他於 1 月 8 日向 Cline 的一名開發者發送後續訊息。他於 1 月 18 日嘗試在 X 上直接傳訊息給 Cline 的執行長。他於 2 月 7 日再次寫信,卻只收到一組自動產生的工單編號,別無其他。他於 2 月 9 日公布。

Cline 在大約三十到六十分鐘後合併了這個修正,也就是拉取請求 9211。該 PR 刪除了三個工作流程檔案:claude-issue-triage.yml、claude-pr-review.yml 和 cline-pr-review.yml,並移除了 publish.yml、publish-nightly.yml、npm-nightly.yaml 和 npm-main.yaml 中的快取,總共七個檔案;由於現在已沒有可依賴的快取命中,安裝步驟改為無條件執行。

Cline 於 2 月 10 日、被 Khan 的貼文引用的公開回應中,接受該調查結果並列出立即緩解措施:移除 issue 與 PR bot 審查工作流程、從處理發佈憑證的 publish 工作流程中移除 actions/cache,以及輪替相關憑證,包括 bot、provider 與 publishing token。它也承認其處理方式:「我們承認,我們對你最初報告的回應時間令人無法接受。一份 1 月 1 日提交的報告,不應該需要到 2 月 9 日公開揭露才獲得處理。」

2月11日,Cline 表示它已完成 VSCE_PAT、OVSX_PAT 與 NPM_RELEASE_TOKEN 的全面輪換,並且對 2025年12月21日至2026年2月9日期間、全部三個發佈管道上的每個版本進行稽核後發現,每個 Marketplace 與 OpenVSX 版本都對應到一個已打上標籤的 GitHub 發行版,且所有 41 個 npm 版本都與原始碼一致。它的結論是,在「所稱的暴露期間內」並未發布任何未經授權的版本。六天後,它在上述引用的訊息中更正紀錄:npm 權杖並未被撤銷,而 2.3.0 就是用該權杖發布的。

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.

已確立、已歸因、未解決

• 已確立。工作流程設定是公開的,且是在修正之前發布的。Khan 在儲存庫的鏡像上重現了提示注入。Cline 合併了補救措施,並發布了一份安全公告,確認 2.3.0 的發布、新增的 postinstall 行、未變更的 CLI 二進位檔、八小時的時間窗口,以及權杖失效。npm registry 中 2.3.0 和 2.4.0 的時間戳記與公告中的時間相符。檔案庫將該紀錄評為 critical,信心等級為 A,並記錄了實際損害,且沒有爭議標記。

• 已歸因,但尚未確立。是誰發布 2.3.0,仍屬未定歸因。由 Michael Bargury 與名為 Raptor 的自動化調查工具於 2 月 19 日發布的鑑識分析報告,點名一個 GitHub 帳號 glthub-actions,並高度確信地指出:該帳號 fork 了 cline/cline、於 2026 年 1 月 28 日 03:51 UTC 以注入的標題開啟 issue 8904,且利用某個 fork 提交從 Gist 執行酬載。Khan 已確認 gcbrun 與 Dev11940518 這兩個帳號是他本人的,而 glthub-actions 不是。該報告發布時,該帳號已被刪除或停權,而 Cline 並未指名任何人。請將該身分視為第三方調查發現。

爭議在於事件性質,而非事實。Bargury 評估此事件符合安全研究示範,而非惡意行動,並引述其無害酬載以及該行為者過去針對 New Relic 自動化儲存庫的紀錄。Cline 稱之為未經授權的發佈,而 Khan 寫道,發佈 2.3.0 的行為者「據推測」就是污染快取的同一個人。沒有人證明存在造成傷害的意圖,也沒有人證明不存在。

• 未解決。Khan 自己在發布前的註記對某個要點相當謹慎,而後續報導有時會把它簡化:在 2026 年 1 月 31 日至 2 月 3 日之間,有數次夜間執行因 Post Checkout 步驟失敗,該步驟沒有產生任何輸出,而這正是 Cacheract 的入侵指標;分診工作流程是最明顯的途徑,但並未被證實是該活動的進入點。也沒有任何一方公布證據顯示 Marketplace 或 OpenVSX 權杖曾被使用;任何人所產出的唯一產物就是 npm 建置。

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.

之後有什麼改變?

這次修復同時落實在好幾個層面上,而每個層面都值得逐一指名,因為它們回應的是這起失敗的不同部分。外部人士可觸及的那個工作流程是被刪除,而不是被縮小範圍。快取是從四個持有發佈機密的發佈工作流程中移除,而不是從整個儲存庫移除,而這正是阻斷樞轉的變更。憑證已輪替,且在 2 月 17 日的修正之後,正確的 npm 權杖已被撤銷。Cline 的安全公告指出,npm 發佈現在透過 GitHub Actions 使用 OIDC 來源證明,而 StepSecurity 的中繼資料分析顯示了這為什麼重要:合法發佈早已帶有來源證明,而 2.3.0 是由真人帳號發佈的異常案例。缺口在於,長效權杖路徑與信任發佈並存未關閉,而這正是 Endor Labs 主張維護者應關閉的具體事項。Cline 發佈了 GHSA-9ppg-jx86-fqw7,將 2.3.0 標為棄用並註明不應安裝,並指引使用者改用 2.4.0 或更新版本。

{{1}}Khan 的結構性建議{{/1}}比{{2}}已實作的部分{{/2}}走得更遠,且值得記錄為{{3}}他的{{/3}}建議,而非{{4}}Cline 的{{/4}}:{{5}}從任何分流工作流程中移除 Bash、Write 和 Edit{{/5}},只留給它{{6}}檔案讀取{{/6}}和{{7}}它所需的特定 GitHub CLI 呼叫{{/7}};{{8}}絕不要在持有生產發佈密鑰的作業中還原快取{{/8}};並且{{9}}讓夜間發行版擁有自己的登錄命名空間和專用的非生產發佈身分{{/9}},以致{{10}}遭竊的夜間權杖根本無法發佈穩定版{{/10}}。

修復與惡意發布之間相隔八天,正是這個細節讓這筆紀錄值得留存。這條鏈上的每一步都是已知手法;Khan 曾發布該快取污染工具,而 Aikido Security 於 2025 年 12 月的 PromptPwnd 研究也記錄了相同的分流錯誤設定模式。把這些環節組成一起供應鏈事件的,是一個讓陌生人的文字得以進入 shell 的工作流程、一個與持有發布金鑰的工作共用的快取,以及一次漏掉某項憑證的權杖輪替。三項修復中的任何一項單獨都能斬斷這條鏈;第三項卻晚了八天到來。