RISC Zero Security Deep Dive: Architecture, Risks, and Review Methodology
三句話摘要
以 RISC Zero 為例,講解零知識虛擬機(ZKVM)的架構原理、常見安全漏洞與程式碼審計清單。 RISC Zero 的安全核心在於訪客程式碼:所有輸入驗證必須在此完成,任何在訪客無法驗證的事實都要寫入 Journal 交由驗證者處理,且永遠不能忘記核對 Image ID 與 32 位元溢位兩個隱性地雷。 Host/Guest 分離是架構核心:主機(Host)是普通 Rust 程式,可存取網路與資料庫,負責準備輸入變數;訪客(Guest)是真正被驗證的邏輯,與 EVM 類似,只能使用主機傳入的資料。驗證者絕不信任主機,主機的任何斷言若未寫入 Guest 並提交到 Journal,驗證者無從確認。
重點整理
重點- 1
Host/Guest 分離是架構核心:主機(Host)是普通 Rust 程式,可存取網路與資料庫,負責準備輸入變數;訪客(Guest)是真正被驗證的邏輯,與 EVM 類似,只能使用主機傳入的資料。驗證者絕不信任主機,主機的任何斷言若未寫入 Guest 並提交到 Journal,驗證者無從確認。
- 2
ZK 壓縮是上鏈的核心收益:數十萬行的訪客程式碼,可壓縮成驗證器端僅 4 行程式碼加上 BLS 數學運算,鏈上驗證成本約 10 萬 Gas。ZK Rollup 正是利用此特性,讓鏈下龐大的執行邏輯只需一個極小的鏈上驗證器。
- 3
訪客程式碼是最高風險區:所有未在訪客程式碼中驗證的輸入(如地址與餘額的關聯、區塊哈希的正確性),都必須寫入公開 Journal 交由驗證者處理,否則攻擊者可任意偽造。示範案例中連續揭露三層漏洞:RPC 未驗證綁定、缺少 Merkle 帳戶證明、區塊哈希未驗證。
- 4
32 位元環境與依賴庫是隱性地雷:RISC Zero 是 32 位元系統(上限 40 億),Rust 預設在 release 模式下靜默溢位;需在 `Cargo.toml` 啟用 `overflow-checks = true`。另外,使用多執行緒、隨機數、檔案 I/O 的第三方加密庫,在訪客程式碼中會直接編譯失敗。
實用技巧與重點
乾貨- 平台與工具
- RISC Zero(ZKVM 框架,Rust 編寫)
- SP1(類似 RISC Zero 的另一 ZKVM,講者另有部落格說明)
- StarkNet(使用 Cairo 語言,領域特定語言 DSL)
- Aztec、Miden、Aloe(其他使用 DSL 的 ZK 平台)
- 具體數字
- 鏈上驗證成本:約 10 萬 Gas
- RISC Zero 是 32 位元系統:最大值 2³² = 約 40 億
- 大型 ZK Rollup 訪客程式碼:數十萬行;鏈上驗證器:僅數行
- 六個核心 API 函式
- `entry_point!` — 定義訪客程式入口(main)
- `env::read()` — 讀取私密輸入
- `env::commit()` — 寫入公開 Journal(所有人可見)
- `ExecutorEnv` — 建構/執行環境,傳遞變數給訪客
- `prover.prove()` — 執行訪客程式並輸出收據
- `receipt.verify(IMAGE_ID)` — 驗證收據
- 以太坊餘額證明所需輸入
- 地址、餘額、區塊哈希、稀疏 Merkle Tree 帳戶證明
- 三層漏洞遞進案例
- RPC 在主機執行但地址未傳入訪客 → 餘額可偽造
- 地址傳入但未做 Merkle 帳戶驗證 → 地址與餘額關聯仍可偽造
- 區塊哈希未驗證 → 攻擊者可填入任意鏈的區塊哈希
- 安全設定
- `Cargo.toml` 加入 `overflow-checks = true`
- 訪客程式碼中 `panic!` 是合法錯誤處理;主機 panic 則造成 DoS
- 學習資源
- RISC Zero 官方文件
- SP1 部落格(講者撰寫)
- Rare Skills ZK Bootcamp(Jeffrey 主辦)
- ZK Book(免費)
- Ingopup Circom 課程
- 審計清單(7 點)
- 關鍵邏輯全部在訪客程式碼內
- 所有輸入在訪客程式碼中驗證或寫入 Journal
- Journal 不含任何私密資訊
- 留意 32 位元溢位問題
- 資源消耗有界(無無限迴圈、無任意長度字串)
- 驗證者:讀收據、驗 Journal 條目、核對 Image ID
- 主機寫入順序與訪客讀取順序完全一致
結論
結論“RISC Zero 的安全核心在於訪客程式碼:所有輸入驗證必須在此完成,任何在訪客無法驗證的事實都要寫入 Journal 交由驗證者處理,且永遠不能忘記核對 Image ID 與 32 位元溢位兩個隱性地雷。”
完整解析
詳細零知識虛擬機(ZKVM)技術讓開發者能在不洩漏私密輸入的前提下,向外界證明「某段程式碼曾以特定方式執行且結果正確」。RISC Zero 是目前最受關注的通用型 ZKVM 之一,其最大優勢在於開發者可直接用 Rust 撰寫程式邏輯,無需學習 Cairo、Circom 等領域特定語言,也無需自行設計底層電路約束——那些複雜的數學工作由 RISC Zero 團隊代勞。
架構上,RISC Zero 將程式分為「主機(Host)」與「訪客(Guest)」兩層。主機是一般的 Rust 程式,可以存取網路、資料庫與外部 API,其職責是收集所有需要傳入訪客的輸入變數,然後啟動 Prover 執行;訪客程式則類似 EVM 智能合約,與外部世界完全隔離,只能使用主機注入的變數。Prover 執行後輸出一份「收據(Receipt)」,這是一份數學證明,記載訪客程式的執行結果。驗證者(Verifier)僅需讀取收據,不必重新執行任何程式碼,便可確認執行的正確性——這正是壓縮的威力:數十萬行的訪客邏輯,最終只需要約 4 行程式碼加上 BLS 數學運算在鏈上完成驗證,消耗約 10 萬 Gas。
講者以「證明某以太坊地址持有超過一定數量 ETH」為案例,逐步演示三層安全漏洞。第一版程式碼在主機直接呼叫 RPC 取得餘額,但未將地址傳入訪客,導致驗證者無法確認餘額究竟屬於哪個地址;修正後將地址傳入並寫入公開 Journal,驗證者才能對應地址與收據。然而第二層問題隨即浮現:雖然地址與餘額都傳入了訪客,卻缺少 Merkle 帳戶證明,攻擊者仍可在主機端填入任意組合的地址與餘額,訪客無從驗證兩者的真實綁定關係。第三層是最隱蔽的:即使加入了完整的 Merkle 驗證,程式仍未驗證區塊哈希的正當性——攻擊者可填入任意鏈的舊區塊哈希,讓證明通過但指向錯誤的鏈上狀態。最終正確的做法是在訪客程式中完成 Merkle 驗證後,同時將區塊哈希提交到 Journal,交由驗證者搭配輕客戶端證明(Light Client Proof)或最終性證明(Finality Proof)來確認其真實性。
實務審計上,講者強調幾個常被忽略的技術細節。RISC Zero 執行於 32 位元環境,Rust 在 release 模式下預設靜默溢位,必須在 `Cargo.toml` 明確啟用 `overflow-checks = true`,否則算術溢位將在訪客程式碼中無聲無息地產生錯誤結果。訪客環境也不支援多執行緒、隨機數生成與檔案 I/O,許多加密庫在底層使用了這些功能,直接引入會導致編譯失敗,需特別篩選相容的依賴套件。此外,訪客程式碼中的無界迴圈與任意長度輸入,會使 Prover(通常是第三方高效能機器)承受高昂成本,形成資源耗盡的 DoS 攻擊面。最後,Image ID 的驗證不可省略——每支訪客程式都有唯一的 Image ID,若驗證者未核對此欄位,攻擊者可用任意惡意程式的收據偽裝成合法程式的執行結果。
關鍵時刻
Pipeline v2帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。
事實查核
Pipeline v2說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。

