KeyFrame內部研究專用

Learn Solidity | Reentrancy Attacks (And How To Fix It)

Alejandro Paños·6月27日週六·15 min英文

三句話摘要

智能合約中的重入攻擊原理、危害與防護方法。 遵循CEI模式執行函數是防止重入攻擊的核心防線,先修改狀態再進行外部呼叫是編寫安全智能合約的基本原則。 CEI模式是智能合約函數的正確執行順序:Checks(檢查)→ Effects(效果,更新狀態)→ Interactions(互動,外部呼叫)。違反此順序會使函數成為可重入的,攻擊者可以在狀態更新前反覆觸發。

重點整理

重點
  • 1

    CEI模式是智能合約函數的正確執行順序:Checks(檢查)→ Effects(效果,更新狀態)→ Interactions(互動,外部呼叫)。違反此順序會使函數成為可重入的,攻擊者可以在狀態更新前反覆觸發。

  • 2

    重入攻擊的實際流程:攻擊者先向受害合約存入以太幣以滿足提款條件,再呼叫提款函數,此時因為外部呼叫(transfer)先於狀態更新,觸發攻擊合約的receive函數,該函數又會再次呼叫提款,如此循環直到合約被掏空。

  • 3

    修復只需交換函數執行順序:先檢查餘額、更新映射中的使用者餘額為零、最後再進行外部呼叫。這樣當receive函數被觸發而再次呼叫提款時,就會在檢查階段因餘額為零而被revert,杜絕迴圈。

  • 4

    實戰演示結果對比:有漏洞的合約被攻擊者從存入的10個以太幣變成11個(含攻擊者自己的1個),受害合約餘額降至零;修復後的合約則在攻擊時直接revert,攻擊失敗。

實用技巧與重點

乾貨
  • 核心概念
  • CEI模式:Checks → Effects → Interactions
  • 易出錯的順序:Interactions(外部呼叫)→ Effects(狀態更新)
  • 有漏洞的Faulty Contract關鍵段
  • ```
  • 存款函數(deposit):以太幣進入,balance映射增加
  • 提款函數(withdraw):
  • 檢查:require(balances[msg.sender] != 0)
  • 互動:call外部轉帳(此時balance還未更新)
  • 效果:balances[msg.sender] = 0
  • ```
  • 攻擊合約(Attacker Contract)邏輯
  • 建構器:傳入受害合約地址
  • attack函數:存1個ETH、呼叫withdraw、觸發receive
  • receive函數:在balance尚未更新時,只要受害合約餘額 ≥ 1 ETH,就重複呼叫withdraw
  • 修復後的Fixed Contract關鍵段
  • ```
  • 檢查:require(balances[msg.sender] != 0)
  • 效果:balances[msg.sender] = 0(先更新)
  • 互動:call外部轉帳(此時balance已為0)
  • ```
  • 實驗數據
  • Faulty合約:初始10 ETH → 被攻擊後變0,攻擊者得11 ETH
  • Fixed合約:攻擊transaction直接revert,無法進行

結論

結論

遵循CEI模式執行函數是防止重入攻擊的核心防線,先修改狀態再進行外部呼叫是編寫安全智能合約的基本原則。

完整解析

詳細

重入攻擊是智能合約最危險的漏洞之一,已在過去造成數十億美元的資金損失。其核心原因在於函數執行時打破了CEI模式的正確順序。當開發者在更新合約狀態前先進行外部呼叫(如轉帳以太幣)時,就會給攻擊者製造機會。

以視頻中的有漏洞合約為例,當用戶呼叫提款函數時,合約會先檢查該用戶的餘額是否大於零,然後直接將以太幣轉帳給用戶(透過低級call函數),最後才將用戶在合約內的餘額記錄清零。看似合理的邏輯,卻埋下致命漏洞。攻擊者可以建立另一份合約,在其中部署一個特殊的receive函數。當攻擊合約向受害合約存入1個以太幣後呼叫提款,受害合約會進行外部轉帳。此時攻擊合約的receive函數被觸發,趁著受害合約內的餘額映射尚未清零,它再次呼叫提款函數。由於條件檢查仍然通過,受害合約會再次轉帳。這個過程會一直重複,直到受害合約的所有資金被抽乾。視頻實驗清晰展示了這一攻擊:初始10個以太幣的合約在遭攻擊後餘額歸零,而攻擊者成功取走11個以太幣(含自己最初存入的1個)。

修復方法看似簡單卻極為有效:只需調整函數內三個步驟的執行順序。將「更新餘額映射」這一步驟提到「外部轉帳」之前執行。這樣當receive函數被觸發而重新呼叫提款時,由於該用戶的餘額已在映射中被清零,函數會在最初的檢查階段就因為revert而停止,完全阻斷了重入的可能性。視頻的第二個實驗驗證了此修復的有效性:同樣的攻擊合約面對遵循CEI模式的合約時,attack交易直接失敗,攻擊者無法竊取任何資金。

這個案例強調了一個至關重要的設計原則:在編寫任何進行外部呼叫的函數時,必須確保所有狀態更改都在外部互動之前完成。這不僅關乎單一合約的安全,更涉及整個協議的資金安全與用戶信任。

關鍵時刻

Pipeline v2

帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。

事實查核

Pipeline v2

說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。

更多「Web3 安全」的內容

IF YOU OWN XRP YOU NEED TO SEE THIS PRICE MANIPULATION! ⚠️
8 min
Web3 安全英文8月14日

IF YOU OWN XRP YOU NEED TO SEE THIS PRICE MANIPULATION! ⚠️

Zach Humphries

  • 機構支撐的積極意義:價格操縱常被視為負面,但Ripple掌握大量XRP供應與escrow,在熊市期間提高價格下限,實際上替零售投資者鎖定了低風險的積累區間,這不是剝削而是市場穩定機制。
  • 歷史模式驗證:2024年7月至11月XRP在50美分附近橫盤整理,低點觸及42美分(wick),高點65美分;隨後11月5日至12月5日單月上漲456%,年底到2025年初累計漲幅534%,這個歷史周期正在1美元價位重演。
  • 比特幣聯動邏輯:講者在4-5月就預測「如果比特幣跌至60k以下,XRP會跌至1美元或更低」,此預測精準應驗,反映出熊市中兩者的明確連動關係。
Minimmit, Multimmit and the New Consensus Frontier with Patrick O'Grady
72 min
Web3 安全英文PODCAST8月5日

Minimmit, Multimmit and the New Consensus Frontier with Patrick O'Grady

Zero Knowledge

  • 反向 Linux 架構:Commonware 刻意暴露棧各層級控制,讓開發者自訂執行環境、共識機制、密碼學實現,而非像 Cosmos SDK 只允許應用層以上定制。2-3 個月能組裝一條定製鏈,代價是額外深度但回報是長期維護成本降低及效能優化彈性。
  • 容錯假設的典範轉移:Alpine Glow(Solana 2025)實現單輪投票定終的關鍵是將容錯預算分離為獨立的 Byzantine 和 Crash 容限。傳統系統把 33% 當一個整體預算;新模型允許 20% 惡意加 20% 崩潰,打破了 PBFT 理論界線,釋放單輪設計空間。
  • Minimet 與 Multimet 的遞進:Minimet 是 5F+1 設定下的乾淨構造,實現更短視圖延遲;Multimet(剛發布)進一步允許並行 mini-commits 且驗證者可推翻領導者審查,使用者交易在全球分布式網路達到 200-300 毫秒端到端定終。
Private Information Retrieval (PIR) with Alex Hoover
64 min
Web3 安全英文PODCAST7月29日

Private Information Retrieval (PIR) with Alex Hoover

Zero Knowledge

  • PIR 保護的是訪問模式,不是資料本身
  • PIR 與加密不同,它關注的是隱藏「客戶端查詢了什麼」,而非「資料是否加密」。在公開資料庫(如區塊鏈)上,客戶端可以在不洩露查詢對象給伺服器的情況下檢索特定條目,解決了輕量級客戶端的隱私和防審查問題。
  • 客戶端預處理方案是突破瓶頸的關鍵