安全掃描
有效地回答一個問題:這些專案目前是否暴露於值得關注的依賴項漏洞?「值得關注」的定義包括已被編目且可觸及的漏洞,或是尚未完全反映在稽核資料庫中的活躍事件。
與單純的 npm audit 相比,其附加價值在於研究層。漏洞資料庫的更新總是有時差,而惡意套件事件通常以取消發布的方式處理(完全沒有可查詢的公告)。因此,此掃描將確定性工具與針對目前正被積極利用的漏洞所進行的即時研究相結合,並直接檢查鎖定檔案中的那些套件名稱——這是最快且可靠的訊號,沒有任何稽核工具能提供。
預設為唯讀:此技能僅進行調查與報告。僅提出修復建議;未經使用者同意不得套用版本更新(它們可能會破壞建置)。
使用時機
- 「調查安全性」/「檢查漏洞依賴項」/「執行安全掃描。」
- 「我們是否受到 <某個 CVE、GHSA 或套件入侵事件> 的影響?」——使用者讀到了相關消息,想了解自己的暴露風險。
- 定期檢查(可與
schedule技能組合,用於週期性雲端掃描——請參閱結尾)。
步驟 1 — 範圍
決定要掃描的範圍。預設為目前專案;如果使用者措辭寬泛(「我們的專案」、「所有專案」、「整個產品線」),則提供多儲存庫掃描。
- 目前專案:你所在的儲存庫。
- 多儲存庫:列舉目前儲存庫旁邊的同級儲存庫——即當前 Git 根目錄的父目錄(通常是
~/projects/*/或~/src/*/)。在開始走訪前,務必先與使用者確認目錄,而非直接假設;錯誤的猜測會浪費長時間的掃描。針對每個儲存庫,透過清單檔案偵測生態系(見下文),逐一掃描,並按專案報告結果。
步驟 2 — 偵測生態系並定位鎖定檔案
每個專案中,若存在其鎖定檔案,則表示該生態系存在:
| 生態系 | 清單檔案 / 鎖定檔案 | 通常位置 |
|---|---|---|
| npm | package-lock.json | frontend/ 或儲存庫根目錄 |
| Go | go.mod / go.sum | backend/ 或儲存庫根目錄 |
| Python | poetry.lock、requirements.txt、uv.lock | 儲存庫根目錄 |
| Swift/SPM | Package.resolved | ios/ 或 .xcodeproj 目錄 |
你掃描的是鎖定檔案,而非清單檔案:它鎖定了實際安裝的精確傳遞依賴版本。
步驟 3 — 確定性基準(每個生態系)
執行生態系本身的工具。這些工具能捕捉所有已存在於漏洞資料庫中的項目。偏好具有可達性分析的工具(它們只報告你的程式碼實際能觸及的漏洞)。
- npm:
cd <dir> && npm audit --omit=dev --audit-level=high(會發送給使用者的部分)以及純npm audit(全部,僅供參考)。無可達性分析——會過度報告;對生產環境的發現應加權處理。 - Go:
govulncheck ./...——具備可達性分析(僅標記在被呼叫的程式碼中的漏洞);使用go install golang.org/x/vuln/cmd/govulncheck@latest安裝一次。這是這些工具中的黃金標準。 - Python:
pip-audit(或pip-audit -r requirements.txt)。 - 任何生態系,或當工具缺失時:使用
osv-scanner掃描鎖定檔案,可透過容器執行以避免安裝任何東西:<runtime> run --rm -v "$PWD:/src:ro" ghcr.io/google/osv-scanner:latest scan --lockfile=/src/<lockfile>。 資料庫最廣泛;作為 Swift/SPM 的備用方案,該生態系缺乏完善的第一方工具。
記錄每個工具的報告。區分生產環境/可觸及的漏洞與開發/建置時的漏洞——建置工具中永遠不會發送的高風險漏洞,與運行時依賴項中的漏洞,其意義截然不同。
步驟 4 — 研究活躍的威脅態勢(附加價值)
這是單純的稽核無法做到的。使用 WebSearch / WebFetch 找出目前活躍的威脅,然後將名稱帶到步驟 5。
- 專案生態系中最近的供應鏈安全事件:搜尋最近的 npm/PyPI/Go 入侵和惡意軟體活動;查看 GitHub Advisory Database (github.com/advisories) 和 OSV (osv.dev) 上近期發布的、涉及你在步驟 2 中看到的套件的條目。
- 如果使用者指定了某個 CVE / GHSA / 事件,請擷取權威性的安全公告並提取精確的受影響套件名稱和版本範圍——這是你將與鎖定檔案比對的內容。
- 偏好第一手來源(安全公告、維護者的貼文、註冊機構的安全通知),勝過彙整新聞的頭條;當某些資訊未經確認時,請註明。
保持時效性:為每個說法標記日期,並說明你的研究時間範圍(例如「過去約 8 週內公開的活躍事件」)。
步驟 5 — 將名稱與鎖定檔案直接交叉比對
對於在步驟 4 中發現的每個套件,不要等待稽核工具——自行檢查鎖定的依賴樹。這是領先指標步驟:
# npm
cd <dir> && npm ls <package>
grep -n '"<package>"' package-lock.json
# Go
grep -n '<module-path>' go.sum
# Python
grep -in '<package>' poetry.lock requirements.txt uv.lock 2>/dev/null
# Swift
grep -rn '<package>' --include=Package.resolved .
然後將鎖定的版本與安全公告中影響範圍進行比對。每個名稱有三種結果:暴露(存在且位於範圍內)、安全(不存在,或存在但位於範圍外)、不確定(無法完全解析的傳遞依賴版本——進一步調查或標記出來)。
步驟 6 — 報告
每個專案,先給出結論,然後是證據:
- 暴露 — 套件名稱、鎖定版本、安全公告/事件、是否為生產環境可觸及,以及具體的修復措施(有目標的版本提升;絕不使用盲目的
npm audit fix)。如果可能已安裝了受感染的版本,請注意其 postinstall 指令可能已經執行——這是ignore-scripts預設值之所以重要的主要原因。 - 安全 — 已檢查且不存在的已研究活躍威脅列表。說明你檢查了什麼,讓「安全」這個結論有意義。
- 不確定 / 未涵蓋 — 工具鏈薄弱的生態系(Swift)、無法解析的傳遞依賴,或者無法確認影響範圍的研究。指出存在的差距,而非暗示已全面覆蓋。
不要暗示你已發現所有問題。說明檢查的時間範圍以及實際掃描的生態系。
組合使用
- 定期掃描:將此技能的流程交給
schedule技能,以進行跨儲存庫的每週雲端執行,這樣新的安全事件就能在數天內被發現,而非等到下次有人想到檢查時。 - 發布或推送前:執行範圍限定的單一專案掃描。如果專案中已有,它可以與
make audit/make secret-scan等推送前步驟自然搭配。
備註
- 稽核工具是落後指標;新聞和此技能的步驟 4 是領先指標。當兩者不一致時——研究指出某個套件已遭入侵但工具卻保持沉默——請信任直接的鎖定檔案檢查並將其視為活躍威脅。
npm audit報告的是安全公告的嚴重性,而非你的可被利用性(無可達性分析)——它會過度報告。govulncheck則相反,是當生態系提供時應優先採用的模型。- 此技能回答的是暴露風險。修復(版本提升、鎖定版本、針對性的
npm rebuild)是另一個需要使用者批准的操作——指出修復方案,但不要未經提示就執行。