部落格 發布於 AIA: 2026年6月1日

TrapDoor:被投毒的 .cursorrules 和 CLAUDE.md 如何讓 AI 程式助手自己偷走開發者憑證

Socket 揭露 TrapDoor 這個跨 npm、PyPI、Crates.io 的供應鏈攻擊:它散布超過 34 個惡意套件、384 個以上版本,目標是偷開發者的 secrets 和加密貨幣錢包金鑰。比較特別的是,攻擊者不只放惡意套件,還投毒 AI 程式助手會讀的 .cursorrulesCLAUDE.md:指令藏在零寬字元(zero-width Unicode,看不見的隱藏字元)裡,再透過看似無害的文件類 pull request 送進熱門 AI 專案。之後如果開發者複製這些 repo 並打開 AI 程式助手,助手可能把檔案內容當成開發指引,進而被引導去跑假的「安全掃描」並外傳本機 secrets;防禦重點是把 AI 助手的指令檔視為不可信輸入,而不是無害設定。

Indirect Prompt InjectionConfiguration PoisoningConfiguration ReviewAI Supply ChainAI Coding Agent
9 項對應的 AIDEFEND 防禦手法

威脅分析

  • 兩條入侵路徑,其中一條比較特別。 TrapDoor 一方面走傳統惡意套件路線,另一方面把 AI 程式助手會讀的設定檔(.cursorrulesCLAUDE.md)變成藏指令的地方,讓助手可能被引導去讀取並外傳資料。
  • 設定檔投毒這條路,一步一步看。 攻擊者有兩種作法:一是把這些檔案塞進惡意套件,二是對熱門 AI 專案發一個看起來無害的 pull request,例如「docs: add .cursorrules with dev standards」。檔案裡的指令藏在零寬字元裡,在一般 diff 畫面上看不到。之後只要有開發者複製這個 repo、打開 AI 程式助手,助手就會把這個檔案當成開發指引讀進去,並被指示去跑一個「安全掃描」或「錢包安全檢查」。這個被偽裝過的工作流程會把本機的 secrets 找出來,外傳到攻擊者控制的 GitHub Pages 或 Gist。整個過程沒有安裝任何惡意套件。這本質上是一種間接提示詞注入(indirect prompt injection,把指令藏在 agent 會讀到的外部內容裡)。
  • 套件這條路,在安裝、import 和編譯時就會執行。 在 npm 上,postinstall hook(套件裝好後自動跑的腳本)會自動執行 1,149 行的 trap-core.js。在 PyPI 上,套件在被 import 時就執行,從攻擊者的 GitHub Pages 網域抓 JavaScript 下來,再用 node -e 跑。在 Crates.io 上,build.rs 會在編譯期間執行,用一把寫死的 XOR 金鑰把本機的錢包金鑰庫加密,再外傳到 GitHub Gist。
  • 偷走哪些東西,以及攻擊者怎麼篩選。 目標包括 SSH key、AWS 憑證、GitHub token、瀏覽器登入資料庫、環境變數、API key,以及 Solana、Sui、Aptos 的錢包金鑰庫。惡意程式還會用真實 API 呼叫去驗證偷到的 AWS 和 GitHub 憑證,讓攻擊者能分辨哪些還能用、哪些已經失效。
  • 它會留後路,也會擴散。 trap-core.js 會透過 .cursorrulesCLAUDE.md、Git hook、shell hook、systemd、cron 和 SSH,在多個地方留下會讓惡意程式之後再跑的設定;還會重複使用偷來的 SSH key,嘗試橫向移動到其他機器。它另外設計了一層「偽裝層」,刻意把竊取憑證的動作,包裝成聽起來正當的任務 - 安全稽核、錢包安全檢查、雲端設定驗證。
  • 被打破的邊界是「設定檔不是程式碼」這個假設。 一旦 AI 助手把 repo 裡的檔案當成可信任的指令,攻擊者只要有辦法讓一個檔案進到 repo - 不管是透過套件,還是一個文件類的 PR - 就能操控助手的行為。影響範圍是每一個複製這個 repo 的人,而不只是裝了某個套件的人。這次攻擊在 2026 年 5 月 19 到 22 日之間開始散布,那些 PR 來自 GitHub 帳號 ddjidd564,目標包括 browser-use、langchain、langflow、llama_index、MetaGPT 和 OpenHands。

適用的 9 項 AIDEFEND 防禦手法

AID-H-022.001
Client-Side Configuration Enforcement
極高
這次的新攻擊,本質是把 AI agent 設定變更偽裝成一般專案檔案變更:被投毒的 .cursorrulesCLAUDE.md,透過 pull request、套件或打包流程進到專案。客戶端設定檢查與強制執行(client-side configuration enforcement)應該在 commit、merge 或 package 前,檢查這些 agent 設定檔的來源、結構與政策相符性,擋下未經核准的外部設定、遠端 URL、隱藏字元或高風險指令。這樣防線會落在 TrapDoor 進入 repo 或發佈流程之前,而不是等開發者開啟 AI 助手後才處理。
AID-H-023.002
Proactive Package Vetting
極高
TrapDoor 的套件這一半,靠的是 34 個以上的仿冒工具套件(像 eth-wallet-sentinelcrypto-credential-scannersolidity-deploy-guard)被拉進專案。套件信譽、維護者歷史、registry 上架時間、安裝腳本與二進位檔分析,以及已知惡意套件判定,都應該在開發者或 agent 把這些套件加進來之前就先跑完 - 不能等 postinstall 或 import 時的程式碼已經執行才補。
AID-D-001.001
Per-Prompt Content & Obfuscation Analysis
TrapDoor 把指令藏在零寬字元裡,所以在一般 diff 上看不到。單一 prompt 的內容與混淆分析(per-prompt content & obfuscation analysis)正是為這種情況設計的:偵測編碼混淆、隱藏指令,以及進到模型的文字裡的 Unicode 操弄。在助手讀取設定檔之前,就把看不見的 Unicode 標記出來或清掉,等於拔掉這個攻擊用來夾帶指令的載體。
AID-H-002.002
Inference-Time Prompt & Input Validation
就算被投毒的檔案已經送到助手面前,推論時的輸入驗證仍能在它變成實際指令前擋下來。這個控制會檢查並過濾輸入裡的提示詞注入攻擊(prompt injection)特徵 - 例如「忽略前面所有指令」、字元混淆,以及偽裝成換任務的句子 - 並把檔案內容當成要清理的資料,而不是要服從的命令;這樣藏在裡面的「去跑安全掃描並上傳」就不會變成實際動作。
AID-I-001.004
Sandbox Network Egress Restrictions
這個攻擊的兩半最後都要外傳 - 把憑證傳到 GitHub Pages 和 Gist,把驗證請求打到 AWS 和 GitHub API。agent 沙箱、相依套件安裝工作和建置步驟,都採用預設拒絕對外連線,只允許必要 registry;這樣就算竊資程式碼或那個假的「安全掃描」真的跑起來,上傳那一步也會被擋下來。
AID-H-023.001
Sandboxed Dependency Installation
TrapDoor 會在 npm 的 postinstall、PyPI 的 import 時,以及 Rust 的 build.rs 編譯時自動執行。把安裝和建置放在一次性的沙箱環境裡跑,安裝時會自動跑的腳本預設停用,裡面不要掛開發者的 home directory、不要有 SSH key、也不要有長效 secrets,就能把這種自動執行關在裡面,就算惡意套件被拉進來也一樣。
AID-M-009.002
Authority Envelope & Action Risk Classification
一個會去讀 SSH key 和錢包檔案、跑「掃描」、又對外連線的助手,不管 prompt 把它叫成什麼,做的都是高風險動作。把存取 secrets、執行 shell、對外連線都歸類成高風險,並要求這些動作要有明確核准才能進行,系統在執行時才有依據,去拒絕一個其實沒人真的要求過的「安全掃描」。
AID-M-001.002
AI System Dependency Mapping
一旦掌握 TrapDoor 的指標,防禦方需要把清查範圍從套件相依關係展開到相關資產:哪些專案或 lockfile 引用惡意套件,哪些 repo 新增了 .cursorrulesCLAUDE.md,哪些 CI cache、容器或開發者機器可能接觸過這些內容。相依關係與資產盤點本身是輔助控制,作用是把一份 IOC(入侵指標)清單,轉成可追蹤、可分派的清查工作,而不是單獨完成偵測或阻擋。
AID-E-003.003
Malicious Code & Configuration Cleanup
清理不能只停在移除套件。事件應變時要移除被投毒的指令檔、Git 和 shell hook、systemd unit 和 cron 項目,刪掉攻擊者的 SSH key,輪替每一個可能外洩的憑證,並回查對外連線紀錄,確認哪些資料已經被傳出去。

身為資安防禦者,我們應該這麼做

  • 在 repo、lockfile、CI cache 和開發者機器上,搜尋 TrapDoor 指標:GitHub 帳號與網域 ddjidd564ddjidd564.github.io、活動標記 P-2024-001、惡意程式 trap-core.js(48,485 bytes),以及 Rust 用的 XOR 金鑰 cargo-build-helper-2026
  • 找出並審查最近新增或被改過的 .cursorrulesCLAUDE.mdAGENTS.md,尤其是透過外部 pull request 進來的;檢查裡面有沒有零寬字元,以及要求去跑「安全掃描」、「錢包安全檢查」或上傳資料的指令。
  • 設定 AI 程式助手,讓它把 repo 裡的檔案當成資料而不是指令;在讀取放 secrets 的路徑、執行 shell 命令或對外連線之前,要求明確核准。
  • 把套件安裝和建置放進一次性沙箱:postinstall、import、build 腳本預設停用,裡面不要有 SSH key 或正式環境 secrets,對外連線只允許到核准過的 registry。
  • agent 或 PR 帶進來的相依套件,除非已經查過精確套件、版本、維護者歷史和安裝腳本,否則先擋下或送人工審查;把 Socket 原文列出的 TrapDoor 套件名稱一律當成惡意套件。
  • 只要某台機器複製過受影響的 repo,或裝過可疑套件,就輪替它上面的 SSH key、AWS 憑證、GitHub token 和錢包金鑰;並主動搜尋新增的 SSH authorized key、cron 或 systemd 的持久化設定,以及連到 GitHub Pages 或 Gist 的對外流量。

1 個額外的防禦考量

AI 助手指令檔需要像程式碼一樣被審查

除了上面對應的防禦技術,團隊也應該把 AI 助手的指令檔 - .cursorrulesCLAUDE.mdAGENTS.md.github/copilot-instructions.md - 當成資安敏感的檔案來看待。TrapDoor 那種文件式 PR 之所以有效,正是因為這些檔案很少像程式碼一樣被仔細審查,而零寬字元又把它們真正的內容藏在一般 diff 看不到的地方。
建議做法: 在 pull request 裡要求審查指令檔的變更,審查時把隱藏字元和零寬字元顯示出來,並在 agent 讀取 repo 或 prompt 之前,先掃描裡面有沒有看不見的 Unicode 字元。

結論

TrapDoor 是一個有了新散布管道的竊資程式。那些套件是大家熟悉的供應鏈誘餌,但這次攻擊真正的新意,是把 AI 程式助手的設定檔當成可以植入指令的地方 - 於是受害者自己的助手,只因為複製了一個 repo,就去跑那個會偷走自己 secrets 的「安全掃描」。AIDEFEND  在兩條戰線上都對應到該做的事:強制 agent 設定檔的完整性與可信來源、偵測被藏起來的 Unicode 與被混淆的指令、驗證並清理輸入讓檔案內容被當成資料而不是命令、套件執行前先審查、把安裝和建置隔離、預設拒絕對外連線、把存取 secrets 和對外連線歸類成高風險 agent 動作,以及在掌握指標後徹底盤點與清理。