部落格 發布於 AIA: 2026年5月26日

ChromaToast:驗證前載入惡意模型,讓向量資料庫變成遠端程式碼執行入口

HiddenLayer 揭露的 CVE-2026-45829,問題出在 ChromaDB 的 Python FastAPI 伺服器:攻擊者不用登入,只要送一個建立 collection(ChromaDB 裡用來存放一組向量資料與設定的集合)的 API 請求,就能讓伺服器在完成驗證前,就已經下載並執行攻擊者控制的 Hugging Face 模型程式碼。從 API 使用者的角度看,這個請求最後可能還是失敗;但對攻擊者來說,惡意程式碼已經在 ChromaDB 伺服器裡跑過了。

這篇的防禦重點很清楚:載入模型不是單純讀資料,而可能是在執行程式碼。向量資料庫如果允許用戶端指定 embedding 模型(把文字轉成向量,讓系統能做語意搜尋的模型),就必須先驗證身分,再限制模型來源、擋掉 trust_remote_code 這類危險載入設定,並把第一次載入模型的動作隔離起來。

Remote Code ExecutionMalicious ModelsRuntime IsolationVector DatabaseRAG Security
6 項對應的 AIDEFEND 防禦手法
來源: ChromaToast Served Pre-Auth 
作者 Esteban Tonglet (HiddenLayer) · 原文發布: 2026年5月18日

威脅分析

  • 問題從一個看似需要驗證的 API 端點開始。 ChromaDB 內建 API 文件把 POST /api/v2/tenants/{tenant}/databases/{db}/collections 標成需要驗證,所以正常來說,沒有憑證的請求應該一進來就被擋下來。問題在於,ChromaDB 的驗證檢查太晚才執行:攻擊者送出一個沒有憑證的建立 collection 請求,伺服器雖然最後會拒絕它,卻已經先處理請求裡的 embedding 函式設定,並下載、載入攻擊者控制的 Hugging Face 模型。
  • 真正危險的欄位,是模型載入設定。 攻擊者不只告訴伺服器「去載入哪個模型」,還能把額外的載入設定一起塞進請求裡。這些額外設定在程式裡會以 kwargs 傳下去;攻擊者把其中的 trust_remote_code 設成 true,等於要求 Hugging Face 載入器把模型儲存庫裡附帶的 Python 程式碼下載下來並執行。這個設定有合法用途,因為有些模型架構真的需要自訂程式碼;但如果模型儲存庫是攻擊者控制的,這個設定就會變成「請執行攻擊者程式碼」。
  • 真正失守的地方,是執行順序錯了。 ChromaDB 的 Python 伺服器會先解析 collection 設定,建立 embedding 函式,然後才呼叫驗證檢查。也就是說,系統還沒確認呼叫者有沒有權限,就已經去 Hugging Face 抓模型、載入模型,並執行模型儲存庫裡的程式碼。
  • 外表看起來像失敗請求,實際上惡意程式碼已經跑過。 模型程式碼執行完之後,伺服器才拒絕這個未驗證請求,甚至回傳錯誤。對一般觀察者來說,這可能只是一次失敗的 API 呼叫;但對攻擊者來說,伺服器上可能已經建立 shell 連線,讓攻擊者能下命令,或至少已經執行過他準備好的 Python 程式。
  • 影響範圍取決於 ChromaDB 伺服器程序能碰到什麼。 如果漏洞利用成功,攻擊者可能讀到環境變數、API key、掛載的 secrets、本機磁碟上的資料,以及伺服器所在網路能連到的其他服務。HiddenLayer 也指出,V1 API 路徑有相同的執行順序問題,所以只擋其中一個 API 版本不夠。
  • 這不是一般 Web bug 而已,而是 AI 基礎設施的信任邊界問題。 這次被利用的輸入不是普通字串,而是 embedding 模型參照。在 RAG 和語意搜尋系統裡,指定模型常常看起來像設定;但模型載入器可能會把模型儲存庫裡的某些內容當成程式碼來跑。所以模型來源、載入規則、執行隔離和 API 驗證,必須被當成同一條安全邊界來設計。

適用的 6 項 AIDEFEND 防禦手法

AID-H-004.002
Service & API Authentication
極高
這是最直接會切斷攻擊鏈的控制。ChromaDB 不是完全沒有驗證,而是驗證做得太晚:它在檢查呼叫者權限前,就已經載入設定並執行模型。服務和 API 驗證必須放在任何請求控制的模型設定被解析、下載、建立或執行之前。只要呼叫者沒有建立 collection 的權限,伺服器就不應該碰到那個模型參照。
AID-H-003.006
Model SBOM & Provenance Attestation
極高
這條攻擊靠的是:公開模型名稱和用戶端控制的載入設定,還沒經過來源判斷,就一路進到執行期。模型 SBOM(Software Bill of Materials,列出模型檔案、雜湊、模型檔案格式、分詞器(把文字切成模型可讀 token 的工具)、設定和載入程式等組成清單)和來源證明,應該記錄已核准的模型內容、雜湊、來源、模型檔案格式、分詞器、載入程式版本,以及 trust_remote_code 這類設定。ChromaDB server 應該只載入事前核准過、來源和政策狀態都清楚的模型,而不是收到請求後才臨時相信一個外部模型名稱。
AID-H-026.001
Dangerous Construct Detection & Blocking
極高
這裡的高風險結構,不是有人直接在 API 裡輸入 shell 命令,而是 trust_remote_code: true 和攻擊者控制的 kwargs 被一路傳進 AutoModel.from_pretrained()。檢查機制應該在模型真正建立前就預設擋下不安全的模型載入設定、不受信任的遠端程式碼執行、不安全反序列化、shell 回連,以及其他不該出現在模型載入流程裡的程式碼執行行為。
AID-H-003.002
CI/CD Release Gating, Model Artifact Signing & Secure Distribution
正式環境的向量資料庫,不應該因為 client 傳來一個模型名稱,就直接去公開 Hugging Face namespace 抓模型。比較安全的做法是:只有掃描過、簽章過、釘選內容雜湊、並放進內部模型倉庫或鏡像站的模型,才能進入執行期 allowlist。這樣建立 collection 時,使用者只能從已核准的內部模型 ID 裡選,而不是讓每一次 API 請求都變成一次新的供應鏈信任判斷。
AID-I-001.002
MicroVM & Low-Level Sandboxing
如果系統真的需要評估新的第三方 embedding 模型,第一次載入不應該直接發生在長時間運作的向量資料庫程序裡。比較好的做法是放進 microVM(輕量虛擬機,用硬體虛擬化隔出更清楚的執行邊界)或低階 sandbox,裡面不要有正式環境 secrets,也不要掛主機共用檔案系統。這樣就算模型程式碼有問題,也比較不容易碰到 ChromaDB 主機、已儲存的向量資料、掛載憑證或內部服務。
AID-I-001.004
Sandbox Network Egress Restrictions
HiddenLayer 的攻擊路徑會讓攻擊者的程式碼在 ChromaDB 伺服器裡跑起來。模型載入 sandbox 和向量資料庫工作負載都應該採用預設禁止對外連線的政策,只開必要目的地。這樣即使惡意模型程式碼真的開始跑,也比較難建立反向 shell、把憑證送出去,或再下載下一段惡意程式。

身為資安防禦者,我們應該這麼做

  • 盤點所有 ChromaDB 部署,特別是對網路開放的 Python FastAPI 伺服器。至少記錄版本、部署路徑、對外介面、驗證層,以及這台伺服器能不能連到公開 Hugging Face。
  • 優先改用 Rust 版部署路徑,或在有修補版時升級到已修補版本。如果仍然需要使用 Python FastAPI 伺服器,就把 ChromaDB 連接埠限制在可信用戶端才連得到的網路範圍內,並放在網路政策、服務驗證、API 閘道或私有服務路徑後面。
  • 如果團隊暫時不能升級,只能先改自己維護的 ChromaDB fork,或在外面加一層暫時防護,就要把驗證移到最前面:在載入 collection 設定、建立 embedding 函式、下載模型之前,就先確認呼叫者有權限。被拒絕的請求,不應該在被拒絕前先建立或執行任何 embedding 模型。
  • 正式環境的建立 collection 流程,預設擋下由請求控制的模型名稱、kwargstrust_remote_code。如果使用者真的需要可設定的 embedding 模型,就提供已核准的內部模型允許清單,而不是讓使用者直接填公開模型參照。
  • 把核准模型放進內部模型倉庫或鏡像站,並加上掃描、簽章、內容雜湊釘選和載入政策檢查。新的 embedding 模型應該像新的可執行相依套件一樣被審查,而不是當成普通設定值。
  • 把第一次模型載入放進短生命週期沙箱(sandbox,隔離執行環境),裡面不要有正式環境 secrets、不要掛使用者平常的個人目錄,並預設禁止對外連線。

結論

ChromaToast 最值得記住的地方,是它把一件看似普通的設定動作,變成了程式碼執行。這個請求不是直接叫伺服器執行命令,而是要求伺服器用指定的 embedding 模型建立 collection;但只要那個模型參照能拉下遠端程式碼,而且伺服器在驗證前就先載入它,collection API 就會變成驗證前遠端程式碼執行入口。AIDEFEND  在這裡對應到的防線很清楚:API 要先驗證,模型來源要能證明,危險載入設定要擋下,正式模型要走安全發布流程,第一次執行要隔離,對外連線要收斂。