4.2 供應鏈攻擊與相依套件安全#
你信任的代碼,比你想的多#
npm install express # → 拉下 60+ 個間接依賴
cargo add axum # → 同樣數百個傳遞依賴
\[ \text{你實際執行的代碼} \gg \text{你寫的代碼} \quad \text{(比例常是 1:100 以上)} \]
現代應用的安全邊界被迫擴大到整個依賴樹 —— 攻擊者很早就發現了:攻擊你的代碼難,攻擊你信任的依賴容易。
攻擊類型與歷史案例#
timeline
title 供應鏈攻擊史
2016 : left-pad — 作者刪庫,全網構建崩潰(可用性警示)
2018 : event-stream — 維護者移交給攻擊者,注入偷比特幣錢包代碼
2021 : ua-parser-js — 作者帳號被盜,投毒下載礦機
2021 : Codecov — CI 工具被入侵,竊取環境變數(秘鑰)
2023 : PyTorch nightlies — 供應鏈竊密
2024 : XZ Utils 後門 — 花三年潛伏成維護者(國家級)攻擊手法分類#
| 手法 | 機制 | 例 |
|---|---|---|
| 帳號劫持 | 維護者 npm token 被盜 | ua-parser-js |
| 社交接管 | 原作者棄坑,攻擊者「善意接手」 | event-stream |
| 拼錯劫持(typosquatting) | request-js vs request | 假套件 |
| 依賴混淆 | 內部私有套件名被註冊到公網 | 2021 年多公司中招 |
| 構建系統入侵 | 攻 CI/CD 工具本身 | Codecov、SolarWinds |
| 長期潛伏 | 取得信任後植入後門 | XZ Utils(2024) |
XZ 事件(2024)的深刻教訓#
攻擊者 Jia Tan 用兩三年時間:認真貢獻取得信任 → 成為共同維護者 → 執掌發布權 → 在壓縮庫植入針對 sshd 的後門。被發現純屬幸運(一位工程師注意到 500ms 的效能異常)。
\[ \text{供應鏈的終極難題}: \text{開源信任模型(人人可貢獻)vs 完整性需求} \]
部分緩解方案:可復現構建(任何人都可從源碼重現出位元相同的二進位)+ 簽章與透明日誌(Sigstore、cargo auditable)。
防禦實務#
1. 鎖定與審計#
npm audit # 掃已知 CVE
npm audit fix
cargo audit # Rust: RustSec 資料庫
cargo deny # 許可證+重複版本+來源
pip-audit / safety # Python
package-lock.json / Cargo.lock 必須進版控 —— 鎖定=可重現=可審計。
2. 自動化漏洞掃描進 CI(前書 5.2/5.3)#
- run: cargo audit --deny warnings
- uses: github/dependency-review-action@v4 # PR 中新依賴的安全性審查
- run: npx @socketsecurity/cli audit # 偵測安裝腳本/異常行為
3. 減少依賴(治本)#
\[ \text{風險} \propto \text{依賴數量} \times \text{依賴品質} \]
問三題才引入新依賴:
- 標準庫/已有依賴能做嗎?(左-pad 教訓:一個 11 行函數值得依賴嗎)
- 它健康嗎?(維護者數、更新頻率、下載量、開放 issue 品質)
- 它的權限範圍?(帶安裝 postinstall 腳本?要求底層權限?)
4. 收緊安裝行為#
npm ci --ignore-scripts # 禁 postinstall 腳本
npm config set ignore-scripts true
# Cargo.toml:限制來源與拒絕未知 registry
[package.metadata.cargo-udeps]
[dependencies]
5. 秘鑰不進 CI 環境變數之外的地方#
Codecov 教訓:CI 的環境變數(AWS key、token)是供應鏈攻擊的高價值目標 —— 最小權限的 CI 憑證(4.3)、短期 token、OIDC 聯邦登入取代長期密鑰。
防禦層次總結#
flowchart TD
A[引入前: 評估健康度] --> B[引入時: 鎖定+最小腳本]
B --> C[持續: audit 進 CI + 自動更新 PR]
C --> D[構建: 可復現+簽章]
D --> E[執行期: 最小權限 容器 執行時偵測]習題#
- 對你的專案跑
npm audit/cargo audit,把每個漏洞分類為「可升級/需重構/可接受」並說明理由。 - 復現 left-pad 事件:刪除一個深層依賴會影響什麼?
npm ls <pkg>觀察依賴樹。 - 設計「引入新依賴的團隊審核流程」,涵蓋本章三問。