Hacking on Solana | Robert Reith (Accretion)
三句話摘要
Solana 上確實存在自我重入(Self-Reentrancy)漏洞,且多數開發者對此一無所知。 Solana 不是沒有重入漏洞,而是換了一種形式存在;只要合約能執行任意外部指令,自我重入就是真實威脅,CEI 模式是唯一可靠的防線。 Solana 的重入保護被過度誇大:Solana 僅禁止「A 呼叫 B、B 再呼叫 A」的跨程序重入,並限制 CPI 堆疊深度為 4,但這不代表完全沒有重入風險,自我呼叫(self-call)仍完全可行。
重點整理
重點- 1
Solana 的重入保護被過度誇大:Solana 僅禁止「A 呼叫 B、B 再呼叫 A」的跨程序重入,並限制 CPI 堆疊深度為 4,但這不代表完全沒有重入風險,自我呼叫(self-call)仍完全可行。
- 2
多簽合約的狀態轉換漏洞:若執行提案時先執行指令、最後才標記狀態為「已執行」(違反 CEI 模式),攻擊者可在執行中途透過第二條指令撤銷投票,製造「已執行 → 已取消」的非法狀態轉換,甚至重複執行同一提案。
- 3
EVM-on-Solana 的宿主逃逸重入:在 Solana 上執行的以太坊虛擬機新增了一個預編譯合約,允許 EVM 合約呼叫外部 Solana 程序。攻擊者可藉此重入 EVM 合約本身,繞過 static call 限制並實現雙花。
- 4
根本原因是開發者認知錯誤:幾乎每一類受影響合約(多簽、DAO、橋接、閃電貸)都發現了相同的自我重入漏洞,共同原因是 Solana 開發者普遍誤信「Solana 沒有重入問題」。
實用技巧與重點
乾貨- Solana CPI 最大堆疊深度:4 層
- 多簽重入漏洞嚴重等級:Low(因所有成員可看到提案內容)
- EVM-on-Solana 重入漏洞嚴重等級:Critical(可雙花任意 ERC20)
- 受影響合約類型:Multisig、DAO、EVM-on-Solana、Bridge(可呼叫任意合約者)、Flash Loan
- 修復方法一:Checks-Effects-Interactions(CEI)模式,先將效果寫入鏈上帳戶再執行外部呼叫
- 修復方法二:執行互動時將所有關鍵帳戶設為 read-only
- 修復方法三:透過程序自省(introspection)禁止自我呼叫,或封鎖特定指令被外部呼叫
- 講者背景:2.5 年 Solana 審計經驗,前 Neodyme,現創辦 The Cre 安全研究公司
結論
結論“Solana 不是沒有重入漏洞,而是換了一種形式存在;只要合約能執行任意外部指令,自我重入就是真實威脅,CEI 模式是唯一可靠的防線。”
完整解析
詳細在以太坊社群中,重入攻擊(Reentrancy)是最廣為人知的漏洞類型,但當話題轉到 Solana 時,絕大多數文章與文件都會告訴你「Solana 的執行模型天然防止重入」。這個說法技術上並非完全錯誤,但它被過度簡化了,而這種誤解正在造成真實的安全漏洞。
Solana 確實禁止了一種重入:若合約 A 呼叫合約 B,合約 B 嘗試再呼叫回合約 A,Solana 執行時期會偵測到堆疊中已存在 A 且非自我呼叫,直接中止整筆交易。加上 CPI 堆疊深度上限為 4,進一步壓縮了攻擊面。然而,程序呼叫自身(self-reentrancy)從未被禁止。當一個合約設計上允許執行外部傳入的任意指令時,攻擊者就可以讓這個合約在執行過程中再次呼叫自己,並在中間狀態下操縱邏輯。
以多簽合約(Multisig)為例,其提案生命週期為:建立 → 投票 → 達到門檻 → 可執行 → 執行完畢。一個典型的脆弱實作會先檢查提案是否可執行,接著依序執行提案中的所有指令,最後才將提案標記為「已執行」——這正是違反 CEI 模式的寫法。攻擊者只需構造一個包含兩條指令的提案:第一條轉移資金,第二條讓某位成員撤銷投票。當第二條指令執行時,提案投票數跌破門檻,狀態被改回「已取消」,但執行函式最後仍試圖寫入「已執行」,造成「可執行 → 執行中 → 已取消 → 已執行」的非法狀態轉換。若實作上未能正確持久化最終狀態,甚至可能讓同一提案被重複執行。
更嚴重的案例來自 EVM-on-Solana——一個將以太坊虛擬機完整實作於 Solana 指令之上的系統,使得以太坊合約與帳戶可以在 Solana 上運行。開發團隊為此新增了一個預編譯合約,允許 EVM 內的合約呼叫外部 Solana 程序,如同虛擬機內的 Windows 系統呼叫宿主 Mac 機器。審計中發現,攻擊者可利用這條通道讓 EVM 合約重入實作 EVM 本身的那個 Solana 程序,進而操控內部狀態,最終實現對任意 ERC20 代幣的雙花,並能將 static call 強制變為 non-static,此漏洞被評為 Critical 等級。
修復這類漏洞並不複雜:嚴格遵守 CEI 模式,確保所有狀態變更在任何外部呼叫之前就已寫入鏈上;執行互動時將關鍵帳戶設為唯讀;或直接在程序層面偵測並禁止自我呼叫。問題的根源不在於技術困難,而在於整個 Solana 生態的認知盲點——太多開發者相信自己不需要考慮重入。
關鍵時刻
Pipeline v2帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。
事實查核
Pipeline v2說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。

