供應鏈
程式撰寫代理程式會安裝大量套件,而剛遭入侵的相依項是毒化沙箱最直接的途徑之一。供應鏈窗格用於設定 Bromure Agentic Coding 套用於每次套件擷取的各工作區政策。如同窗格本身的描述所述:Bromure 會透過主機 MITM 掃描每次套件擷取(npm、PyPI、Cargo、RubyGems、Maven、NuGet、Go modules、Packagist),並在代理程式看到回應之前套用這些政策;VM 內的 .npmrc / pip.conf 只能進一步限制這些設定——無法放寬它們。請使用各套件的允許清單來進行精準的例外處理。
此窗格將五個可獨立切換的層級分組:年齡限制、OSV 漏洞檢查、套件過濾、安裝指令碼與鎖定檔釘選安裝(後三項需捲動檢視)。本頁記錄這些設定;完整的處理流程——生態系涵蓋範圍、安全性記錄、回應標頭與入侵偵測——則在供應鏈防護章節中說明。
強制執行的運作方式
所有檢查都在主機端的代理伺服器中執行,絕不在 VM 內執行。信譽服務的 API 金鑰(socket.dev、Delpi)僅保存在主機上,絕不匯出至 VM。當某項檢查觸發時,代理伺服器會以 HTTP 451 回應封鎖下載,並附上純文字原因(例如「npm package [email protected] published 4 hours ago — policy requires 2 days minimum」);npm、pip 與 cargo 會逐字印出該文字,因此代理程式與你都能確切看到安裝失敗的原因。遭封鎖的回應帶有標頭 X-Bromure-Block: supply-chain;經改寫的回應帶有 X-Bromure-Rewritten: supply-chain。
政策編輯會即時生效:儲存工作區時會立即將新政策推送至執行中的工作階段——無需重新啟動 VM——且每項變更都會在安全性記錄中以一行 [supply-chain] policy engaged 確認(Window 選單 → Security Log…)。
附註: 已存在於 npm 或 pip 本機快取中的套件永遠不會接觸網路,因此不會對它們進行任何檢查或記錄。安裝期間安全性記錄的靜默,可能只是代表一切都已快取。
年齡限制
年齡限制會拒絕比可設定之截止時間更新的套件版本,其理論是剛發布的版本最有可能是剛遭入侵的套件。這是唯一預設啟用的層級。
- 拒絕比截止時間更新的套件——主開關。預設啟用。
- 最小年齡——以天數為單位的截止時間(步進器,0–90)。預設:2 天。
- 豁免套件——採用
npm:axios(單一生態系)或僅axios(每個生態系)格式的允許清單,不區分大小寫。按一下新增項目以附加一列。
浮動參照(pkg@latest、semver 範圍)絕不會被硬性封鎖:代理伺服器會改寫登錄檔的中繼資料,讓過新的版本從代理程式的角度來看根本不存在,而套件管理員會解析為最新的允許版本。只有釘選參照到過新版本時才會收到 451,並說明套件的年齡與所需的最小值。
附註: Maven、NuGet 與 Go modules 在其標準中繼資料回應中不帶有各版本的時間戳記,因此年齡限制目前不會封鎖這三個生態系。npm、PyPI、Cargo、RubyGems 與 Packagist 則完整涵蓋(就 PyPI 而言,Bromure 會依需求從 PyPI JSON API 查詢發布時間)。
OSV 漏洞檢查
當在 api.osv.dev 上查詢套件(免費,無需金鑰)啟用時,每個已下載成品的生態系、套件與版本都會與 OSV 資料庫進行比對——這是 GitHub Advisory Database、PyPI 公告、Go 漏洞資料庫、RubySec 等來源的免費彙整。任何達到或超過封鎖嚴重性閾值的公告都會以 451 封鎖下載。
- 預設停用——如窗格所述,遞移子套件中的低嚴重性 CVE 不應中斷工作流程。
- 封鎖嚴重性提供低度以上、中度以上、高度以上(預設)或僅重大。
- 涵蓋全部八個生態系;檢查在成品下載時執行,而非在中繼資料擷取時執行。
套件過濾
套件過濾選項按鈕用於選取信譽提供者:無、socket.dev 或 Delpi。這兩個提供者運作方式不同——socket.dev 是代理伺服器在放行擷取之前查詢的預先查核,而 Delpi 則完全取代 npm 登錄檔——因此兩者互斥。切換時會保留已儲存的 API 金鑰,因此在提供者之間切換不會造成資料遺失。
socket.dev
選取 socket.dev 後,將 API 權杖貼入 API 金鑰(取得 API 金鑰連結會開啟 socket.dev 的權杖頁面)。在輸入金鑰之前,下方兩個開關都會維持停用狀態,而空白金鑰無論開關狀態為何都會完全停用 socket.dev。金鑰僅儲存在主機端,絕不進入 VM。
- 封鎖遭入侵的套件(惡意安裝指令碼、標記為惡意軟體、偽冒套件、可疑遙測)——會封鎖具攻擊特徵的供應鏈風險訊號:任何嚴重性的確切惡意軟體指標;而較嘈雜的訊號(例如混淆程式碼、安裝指令碼、偽冒或 shell 存取)僅在 socket.dev 將其評為高度或重大時才封鎖(因此帶有良性
postinstall的套件不會被封鎖)。預設停用。 - 封鎖有已知 CVE 的套件——會依 socket.dev 的漏洞分類,在達到或超過 CVE 封鎖閾值時封鎖(預設高度以上;在此開關啟用前選擇器為停用狀態)。預設停用。
附註: socket.dev 不支援 Cargo。啟用 socket.dev 過濾時,每個 crates.io 成品都不會產生判定結果,並觸發下方描述的未驗證套件擱置——實際上等於每個 crate 版本都會出現一次提示。對於大量使用 Rust 的工作區請停用 socket.dev,否則就要準備好回應提示。
Delpi
選取 Delpi 並輸入 API 金鑰後(取得 API 金鑰連結會開啟 landh.tech),代理伺服器會將每個 npm 登錄檔請求——中繼資料、tarball、稽核,凡是傳送至 registry.npmjs.org 的一切——重新導向至 Delpi 位於 depi-npm-proxy.landh.tech 的 npm 相容安全登錄檔,並由主機注入你的金鑰作為 Bearer 權杖。Delpi 提供預先審查過的套件,因此不是進行各套件查詢,而是整個登錄檔被取代。其他層級(年齡限制、OSV、指令碼移除)仍會在此之上套用:Delpi 取代的是 socket.dev,而非本機政策。
當金鑰欄位為空時,會顯示橘色警告 輸入 API 金鑰——沒有金鑰時 Delpi 維持停用。 如果 Delpi 拒絕該金鑰,npm 安裝會以明確的 Bromure 錯誤失敗、該拒絕會記錄於安全性記錄中,並發出一次性警示。Delpi 僅影響 npm;其他生態系不受影響。
安裝指令碼
即時移除 npm tarball 中的 preinstall / install / postinstall / prepare 會移除惡意 npm 套件用來在安裝時執行程式碼的鉤子。Bromure 會即時改寫 tarball——從套件的 package.json 移除指令碼鍵、重新計算 tar 總和檢查碼、重新 gzip 壓縮——並從登錄檔中繼資料清除完整性雜湊,讓 npm 本身的驗證對於未釘選的安裝仍能通過。移除動作會在安全性記錄中以橘色記錄;一旦發生任何剖析失敗,原始 tarball 會原封不動地通過(此層級採用故障開放,而非中斷格式正確的安裝)。
真正需要安裝指令碼的繫結編譯器(better-sqlite3、node-canvas 等)請填入允許執行安裝指令碼的對象,格式為 npm:better-sqlite3。
預設停用;僅限 npm(PyPI sdist 絕不改寫——setup.py 是任意程式碼)。
鎖定檔釘選安裝
鎖定檔釘選安裝(npm ci、pip --require-hashes)會在鎖定檔中釘選 tarball 完整性雜湊,因此 Bromure 無法在不破壞驗證的情況下改寫這些 tarball。預設情況下它們會未經修改且靜默地通過。
啟用在讓鎖定檔釘選的 tarball 未經修改通過前先詢問(npm ci、pip --require-hashes)即可改為收到詢問:一批中的第一個鎖定檔釘選擷取會彈出一個標題為 Pass through npm ci (lockfile-pinned install) from workspace "<name>"? 的主機對話方塊,提供允許 15 分鐘、允許一次、在本工作階段剩餘時間內允許與不允許選項。整批都會遵循該決定(並行擷取會合併為一個提示);拒絕會以 451 封鎖並記住 60 秒。
附註: 雖然標籤提到
pip --require-hashes,但目前僅針對 npm 的npm ci實作偵測——pip 雜湊釘選安裝不會觸發此提示。
當信譽來源無法連線時
如果已啟用的信譽來源(OSV 或 socket.dev)無法產生判定結果——網路中斷、遭速率限制、驗證失敗、不支援的生態系——Bromure 會採用故障關閉,而非靜默允許。下載會被擱置,並由對話方塊逐一針對套件與版本詢問是否接受該未驗證的套件;拒絕會以 451 封鎖。核准是以各 package@version 為索引鍵,因此單一回應無法涵蓋整個相依圖。
這是刻意設計的防護,用以對抗攻擊者透過誘發速率限制來偷渡套件的手法。這也意味著在啟用 OSV 或 socket.dev 的情況下進行完全離線作業,會對每個未快取的套件出現提示——離線使用時請停用這些層級。在無頭的 SSH/CLI 工作階段中,同樣的問題會在工作區的 tmux 內詢問;不回應即視為拒絕。
設定參考
| 設定 | 類型 | 預設值 |
|---|---|---|
| 拒絕比截止時間更新的套件 | 開關 | 開啟 |
| 最小年齡 | 步進器,0–90 天 | 2 天 |
| 豁免套件 | 清單(npm:axios 或 axios) | 空白 |
| 在 api.osv.dev 上查詢套件(免費,無需金鑰) | 開關 | 關閉 |
| 封鎖嚴重性(OSV) | 選擇器:低度 / 中度 / 高度以上、僅重大 | 高度以上 |
| 套件過濾 | 選項按鈕:無 / socket.dev / Delpi | 無 |
| API 金鑰(socket.dev) | 安全欄位 | 空白 |
| 封鎖遭入侵的套件 | 開關(需要 socket.dev 金鑰) | 關閉 |
| 封鎖有已知 CVE 的套件 | 開關(需要 socket.dev 金鑰) | 關閉 |
| CVE 封鎖閾值 | 選擇器(隨 CVE 開關啟用) | 高度以上 |
| API 金鑰(Delpi) | 安全欄位 | 空白(沒有金鑰時 Delpi 維持停用) |
| 即時移除 npm tarball 中的 preinstall / install / postinstall / prepare | 開關 | 關閉 |
| 允許執行安裝指令碼的對象 | 清單(npm:better-sqlite3) | 空白 |
| 在讓鎖定檔釘選的 tarball 未經修改通過前先詢問 | 開關 | 關閉 |
此處輸入的 API 金鑰存放於主機上工作區的 profile.json 中(絕不在 VM 內);所有信譽呼叫都源自主機代理伺服器。關於安全性記錄、各生態系的攔截細節,以及與這些政策搭配的入侵偵測警報,請參閱供應鏈防護章節。