Supply Chain:Skill / Plugin / Dependency 防禦
你安裝的每一個 skill、plugin、dependency,都不是免費功能。那是一份你替別人簽下去的信任授權。
Hook
你看到一個很紅的 Claude Code skill。 README 寫得很漂亮。
功能也很剛好。
它可以:
- 幫你整理 repo
- 自動生成工作流
- 幫 agent 補更多 command
文件裡只有兩步:
git clone- 執行 install script,複製到
~/.claude/skills/
你照做了。 當下沒有任何異常。
skill 也真的能用。 隔天你看流量紀錄,
發現一筆很奇怪的 outbound HTTP request。 目的地不是你認識的服務。
而 request body 居然帶了你 home 目錄裡的內容片段。
再往下追, 你發現 install script
其實做了幾件你昨天沒注意到的事:
- 掃了 home dir
- 讀了
~/.ssh - 寫了一個持久化設定
- 往外送了一段資料
這不是 skill 比較壞。 而是你昨天把它當成「功能擴充」。
沒有把它當成 supply chain entry。
Learn
攻擊面走到供應鏈,才算真的補完
前兩課看了:
- network exposure
- tool availability
第三課看了:
- MCP tool 與權限面
第四課要補的是:
你到底把多少信任,交給外部提供的程式碼與 artifact。
這就是 supply chain 面。
如果前面三課在講:
你系統現在露出哪些洞,
那這一課在講的是:
誰有機會偷偷幫你再多挖幾個洞。
供應鏈風險不是只有 pip install
很多工程師一聽 supply chain, 先想到依賴包。
這當然重要。 但在 AI agent 時代,
還有幾種同樣危險的來源:
- skill
- plugin
- MCP server
- install script
- model weights / adapter
- 被自動下載的外部 binary
這些東西的共通點是:
它們都帶著你借來的信任, 進到你的系統裡。
第一類:skill / plugin install script
這類東西最容易被低估。 因為它長得不像 dependency。
它長得比較像:
「提升生產力的小工具」 但它一旦附帶 install script,
你就必須把它視為:
可在你環境裡執行的程式碼。
常見風險包括:
- 讀 sensitive path
- 改 shell profile
- 寫 dotfile
- 偷裝背景服務
- 偷做 outbound request
也就是說, 你安裝 skill 的那一刻,
其實是在替它開一條本機供應鏈路徑。
第二類:typosquatting
這是最傳統, 但還是很常見的坑。
例如你以為自己裝的是:
requests
結果打成:
requets
或:
python-dotenv 打成某個相似名稱。
這類風險之所以可怕, 不是技術多高明。
而是它利用的是:
你眼睛看得太快。
第三類:合法 maintainer 被盜
不是每一個有後門的套件, 一開始都長得像惡意包。
有些情況是:
- 專案原本很正常
- 使用者很多
- 大家都很信任
- 後來 maintainer 帳號被拿走
- 新版被塞進惡意行為
所以:
「這個套件以前沒事」 不等於
「這個套件下一版也沒事」。 這就是為什麼 pin version
比永遠追 latest 更像安全流程。
第四類:model artifact / weights
這門課不把重點放在模型研究細節。
但你至少要知道:
model weights 也屬於供應鏈。
如果一個模型、 adapter、
或 inference artifact 本身帶有後門 trigger,
那你在 trust boundary、 context boundary 上做的很多防線,
都有可能被繞開。
對工程師最重要的翻譯是:
不要把模型檔案當成純資料。 它也是你引入的外部依賴。
安裝前 audit:先看危險動作,不是先看 star 數
這門課最實用的規則之一是:
安裝前先 audit,至少先看它會不會碰到你不希望它碰的東西。
如果有 skill:audit-skill 就先跑。
如果沒有,
手動最少也該掃:
- outbound network call
subprocess/ shell 執行~/.ssh~/.gnupg.secrets- dotfile write
這種 audit 不是保證 100% 抓到後門。
但它能把最粗暴的惡意行為, 先擋掉一大批。
一個很短的 heuristic scanner 思路
下面這段不是完整防毒。 只是示範你在 code review 時,
先看哪些 pattern。
這種 heuristic 很土。 但很有用。
因為你不是要在 5 分鐘內證明它絕對安全。
你是要在 5 分鐘內判斷:
它有沒有明顯不該先信任的跡象。
Quarantine 模式:可疑先隔離,不要先啟用
這是很多團隊最缺的一步。
不是所有東西都只能二選一:
- 安裝
- 不安裝
中間其實應該有第三態:
quarantine
意思是:
- 可以先下載
- 可以先讀 source
- 可以先做 audit
- 但不能直接進正式工作流
這個狀態的價值, 是讓人類 ratify
成為明確流程, 而不是事後補救。
Lockfile + version pin 的安全意義
很多人知道 pin version 是為了可重現。
但它同時也是 attack surface 管理。
因為:
每次自動升級, 都等於你重新接受一次外部變更。
你若沒有明確版本, 就等於把 attack surface 的一部分,
交給未來某個你沒看過的 release。
所以:
requirements.txtpoetry.lockpackage-lock.jsonuv.lock
這些不只是 build 工具。 它們也是信任邊界文件。
最小依賴原則:每多一個 dep,就是多一個入口
這條規則很樸素,
卻非常常被忽略:
能不裝就不裝。
因為每多一個 dependency, 不是只多一個功能。
還多了:
- 一個更新節奏
- 一組 maintainer
- 一條安裝路徑
- 一批 transitive dependency
- 一種你未必真的看過的行為
所以有時候最安全的優化, 不是找更會審查的工具。
而是直接少裝。
供應鏈一旦失守,四條邊界會一起被拖下去
這就是為什麼這課放在系列後段。 它不是獨立問題。
它會把前四條邊界一起拖壞。
| 被污染的供應鏈會發生什麼 | 受影響的邊界 |
|---|---|
| 偷走 token / key | trust + privilege |
| 多做 outbound request | data |
| 把惡意內容寫進 memory / note | context + data |
| 悄悄擴大 tool 能力 | privilege + attack surface |
也就是說, supply chain
不是一個附屬章節。 它是 attack surface 的最後一哩。
install script 最值得怕的地方,是它常被當成 setup 雜事
工程師在 setup 新工具時,
注意力通常放在:
- 能不能跑
- 指令是不是成功
- 缺了哪些 env var
這正是 install script 容易穿過防線的時刻。 因為它披著
「只是安裝流程」 的外衣。
但從安全視角, 安裝流程就是權限最高、
最不該被省略審查的時刻之一。
你真正要養成的流程,不是單次警覺
真正可落地的做法,
通常長這樣:
- 來源先分級
- 可疑項先進 quarantine
- 跑 automated audit 或手動 source scan
- pin version / lockfile 記錄
- 明確指定 owner
- 定期 review 是否還需要它
這六步不華麗。 但它們真的能縮 attack surface。
一個判斷句:它是功能,還是供應鏈入口
以後看到 skill / plugin / 依賴時,
不要只問:
「它能幫我做什麼?」
再多問一句:
「它因此能碰到什麼?」
只要答案包含:
- home 目錄
- shell
- 憑證
- 網路
- 自動下載
你就不該把它當成普通小工具。 它是供應鏈入口。
這門課最後要你記住的,不是 paranoia
不是叫你永遠不要用第三方。 而是把信任改成顯式。
不是因為它很紅就信。 不是因為它能跑就信。
不是因為別人貼教程就信。
而是:
先 audit、 先隔離、
先 pin、 最後才決定要不要把它放進正式 attack surface。
AI 協作:學了這個,跟 AI 怎麼配合?
這個技能在 AI 協作中的定位, 是讓你要求 AI 幫你做 install script / dependency 的可疑行為盤點,
而不是只幫你照 README 把工具裝起來。 你的人類優勢:
- 只有你知道哪些本機資產在你的環境裡是絕對不能碰的,例如
~/.ssh、公司憑證、長期 token。 - 只有你能判斷某個外部工具帶來的效率收益,值不值得它新增的供應鏈風險。
可以這樣跟 AI 說:
我有一個第三方 skill / plugin / Python script 想安裝。請先幫我做 supply chain audit:找出 suspicious imports、shell execution、outbound URL、dotfile write、以及任何會讀
~/.ssh、~/.gnupg、.secrets的跡象。最後把它分類成safe-enough-to-review、quarantine、或reject,但不要幫我直接執行安裝。
Do
互動示範
挑戰任務
請寫一個 audit_python_script(path) 函式,讀取目標 Python 檔案內容後,列出可疑 import(至少包含 subprocess、urllib.request、requests)與疑似 outbound URL(http:// 或 https://)。測試檔內容可自行先寫到暫存檔,至少包含 import subprocess、import requests、以及一個 https://evil.example/upload。最後印出固定字串:imports=subprocess,requests;urls=https://evil.example/upload。