Lab-confirmed:本文主要是近期事件拆解與 reference 設計,不是我(Maki)已在 production 全量實跑過的完整防線。Code snippet 為 reference 設計,非實際在跑的版本。
你以為你在裝能力,其實你在繼承攻擊鏈
很多 builder 還把 supply chain 風險想成 pip install 的老問題。
但 agent 時代的 supply chain,早就不只是一個 Python wheel。
它包含 LLM gateway。
它包含 skill marketplace。
它包含 MCP server。
它包含 CI/CD publish token。
它還包含那種「看起來只是方便你加能力」的 plugin 安裝流程。
這些東西一旦被拿下,模型本身不需要有洞。
攻擊者直接站到你和模型之間最肥的地方。
AI gateway 特別危險,因為它天生就是秘密集散地。
OpenAI key、Anthropic key、Azure credential、Kubernetes token、.env、CI secret,常常都在同一層被看得到。
一個被污染的 gateway,不只是偷一把鑰匙。
它是替攻擊者打開整個 AI infra 的服務總開關。
skill 也一樣。
很多工程師以為自己只是在裝一個「能幫 agent 接 Gmail、接 Slack、接 GitHub」的小能力。
實際上你是在執行一段第三方程式,還允許它把 stdout、錯誤訊息、自然語言描述一起送回 agent context。
如果 skill 開發者把 debug print 留在裡面,secret 可能不是被駭走。
而是被你自己餵進 LLM。
這就是 AI supply chain 最不舒服的地方。
它不長得像傳統 malware。
它長得像 productivity。
AI Supply Chain:你到底把什麼裝進了系統
供應鏈風險的重點,不是某一個套件很有名。
而是它位在什麼位置。
Case:
主:2026-03-24,Datadog Security Labs 公開 LiteLLM TeamPCP 事件。兩個真的 PyPI 版本 1.82.7 與 1.82.8 被植入惡意程式,不是假包,不是 typosquat,而是 AI gateway 本體被拿來當載具。Datadog 把它串回 2026-03-19 開始的 Trivy 供應鏈攻擊;Endor Labs 與其他後續分析則把 payload 行為歸納得更直接:先收割 cloud key、SSH key、Kubernetes secret 與 .env,再嘗試橫向移動,最後落持久化 backdoor。LiteLLM 每月約 9,500 萬下載,日均約 340 萬下載,Heise 與多家後續報導都用這個量級估 blast radius。
延伸:事件不是停在套件本身。2026-03-31,TechCrunch 報導 Mercor 也確認受 LiteLLM 事件波及。2026-04-03,WIRED 進一步報導 Meta 暫停與 Mercor 的合作。這個連鎖反應很有代表性:你 compromise 的不只是一個 library,而是整條 AI vendor graph。
次:2026-04-03 發布的研究 Credential Leakage in LLM Agent Skills 分析了 17,022 個 skills。結果很難看:520 個 skill 帶有 1,708 個 credential leakage 問題;76.3% 的洩漏只有同時讀自然語言描述和 source code 才看得出來;73.5% 的問題來自 print / console.log 之類的 debug logging,因為 stdout 會回流到 LLM 可見範圍。社群後來把這件事濃縮成一句很殘酷的話:你不是被駭,你只是跑了 skill。
再下一層:2026-04-15,OX Security 發布 The Mother of All AI Supply Chains。The Hacker News 與 Tom's Hardware 的後續報導把重點講得很清楚:MCP 官方 SDK 的 STDIO 執行模型把 command execution 直接放在 builder 面前,下載量已超過 1.5 億,而風險繼承到 LiteLLM、LangChain、LangFlow、Flowise 等整個生態。這時候你就很難再說「這只是工具,不是 attack surface」。
核心問題:你有沒有把 AI infra dependency 當成 privileged code 在審?
Rule:pin hash,不只 pin version。publish token 分 repo 分 scope 隔離。skill install 前同時掃自然語言描述和 source code。install-time 掃描不要交給會自己呼叫工具的 agent。整條 agent stack 要有自己的 Agent BOM。
Builder 在這裡真正缺的,不是一個更會寫 regex 的模型。
而是把「方便安裝」改回「先隔離、先審、再信任」的工程順序。
| Threat | Mitigation | Validated in (reference) |
|---|---|---|
| 只 pin version,不 pin artifact | 鎖 sha256 hash;CI 驗證 artifact digest;異常版本直接 quarantine | mk-brain deploy hygiene |
| 共用 publish token 被橫向移動利用 | 每 repo 單獨 publish token;publish job 不可讀其他 repo secret;TTL 短化 | ERIKA Bot release helper |
| skill 自然語言描述和 source code 分開審 | install 前跑 audit_skill_install();同時看 prompt text、manifest、source | Inbox Bot skill review |
| skill stdout 把 secret 噴回 LLM | debug logging 預設 deny;stdout 先 redaction 再進 context;高風險 pattern 直接 fail install | mk-brain tool bridge |
| 沒有人知道 agent 依賴了哪些 tool / skill / server | 建 Agent BOM:模型、gateway、skill、MCP server、registry、hash、scope 全記錄 | personal PKI inventory |
Reference 實作(示意非 production code,依你環境調整):
from pathlib import Path
import re
SECRET_RE = re.compile(r"(sk-[A-Za-z0-9]{20,}|AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{20,})")
HTTP_RE = re.compile(r"(requests\.(get|post)|urllib\.request|httpx\.)")
WRITE_RE = re.compile(r"(\.ssh|\.gnupg|\.secrets)")
PRINT_RE = re.compile(r"(print|console\.log)\s*\(")
def audit_skill_install(skill_path: str) -> list[str]:
base = Path(skill_path)
findings = []
corpus = []
for path in base.rglob("*"):
if path.is_file():
text = path.read_text(encoding="utf-8", errors="ignore")
corpus.append((path, text))
merged = "\n".join(text for _, text in corpus)
for path, text in corpus:
if HTTP_RE.search(text):
findings.append(f"{path}: outbound HTTP capability")
if WRITE_RE.search(text):
findings.append(f"{path}: writes to sensitive local paths")
if PRINT_RE.search(text) and SECRET_RE.search(text):
findings.append(f"{path}: suspicious stdout secret exposure")
if "api key" in merged.lower() and HTTP_RE.search(merged):
findings.append("cross-modal risk: NL description + code imply exfil path")
return findings
對應 OWASP:這篇先看哪幾條
LLM03:2025 Supply Chain:這篇處理的就是 gateway、skill、registry、publish pipeline 何時從依賴變成入口。LLM05:2025 Improper Output Handling:很多 skill 洩漏不是發生在 network exfil,而是 stdout 被你自己接回模型。
想動手做? 這篇文的概念可以接著看: 攻擊面邊界
如果你想把這一套落成 builder checklist,直接接: 攻擊面邊界 101 →