淺談智能合約安全審計的基本功:重入漏洞和溢出漏洞


這次我們將解釋智能合約中的兩個經典漏洞:重入和溢出

重入漏洞相信大家都聽說過,那麼什麼是重入漏洞呢?

以太坊的特點之一 智能合約審計服務 是合約可以互相進行外部調用。同時,以太坊的轉賬不限於外部賬戶。合約賬戶也可以擁有以太幣並進行轉賬等操作。當合約收到以太幣時,會觸發回退函數執行相應的邏輯,這是一個隱藏的外部調用。

審計編輯器首先定義了重入漏洞:可以認為合約中所有的外部調用都是不安全的,可能存在重入漏洞。例如:如果外部調用的目標是攻擊者可以控制的惡意合約,那麼當被攻擊合約調用惡意合約時,攻擊者可以執行惡意邏輯,然後重新進入被攻擊合約內部。方式發起意外的外部調用,從而影響被攻擊合約的正常執行邏輯。

我們的目的是為了防禦,那麼作為開發人員如何避免編寫易受攻擊的代碼,作為審計人員如何快速發現有問題的代碼,下面小編就來分析一下如何防範重入漏洞以及如何防范代碼中的重入漏洞。快速找到以下中的重入漏洞:

(1) 作為開發者

從開發者的角度來看,我們需要做的是編寫好的代碼來避免重入漏洞。

1、編寫代碼時,需要遵循先判斷再寫變量進行外部調用的編碼標準(Checks-Effects-Interactions);

2.增加防重入鎖。

(2)作為幣壇審計中心審計員

作為審計人員,我們需要關注的是重入漏洞的特徵:所有涉及調用外部合約的代碼位置都是不安全的。這樣,在審計過程中,需要重點關注外部調用,進而推斷外部調用可能造成的危害,從而判斷這個地方是否會因為重入點造成危害。

至於第二部分的溢出漏洞,我們先來看看什麼是溢出:

有兩種類型的算術溢出或簡單的溢出:上溢和下溢。所謂溢出是指在運行單個數值計算時,當計算結果非常大,大於寄存器或內存所能存儲或表示的容量限制時,就會發生溢出。例如,在solidity中,可以用uint8 表示的範圍是0-255 的256 個數字。實際操作中使用uint8類型計算255+1時,會出現溢出,所以計算結果為0,是uint8類型所能表示的最小值。類似地,當計算結果非常小,小於寄存器或內存存儲或表示能力的極限時,就會發生下溢。比如在Solidity中,使用uint8類型計算0-1時,會出現下溢,所以計算出來的值為255,是uint8類型所能表示的最大值。

如果合約有溢出漏洞, 智能合約審計 會造成實際計算結果與預期結果有很大差異,影響輕量級合約的正常邏輯,重度級合約造成資金損失。但是,溢出漏洞受版本限制。當Solidity = 0.8 時,overflow 會報錯。所以當我們看到0.8版本以下的合約時,一定要注意這個合約可能存在的溢出問題。

下面小編還從開發者和審計者的角度分析瞭如何防止溢出漏洞,以及如何快速發現溢出漏洞:

(1) 作為開發者

1、使用SafeMath防止溢出;

2、使用Solidity 0.8及以上版本開發合約,謹慎使用unchecked,因為unchecked修改代碼塊不會檢查參數是否溢出;

3. 需要謹慎使用變量類型強制。例如,將uint256 類型的參數強制轉換為uint8 類型,由於兩種類型的取值範圍不同,可能會導致溢出。

(二)作為幣壇審計中心審計員

1.首先檢查合約版本是否低於Solidity 0.8或是否有未檢查的修改代碼塊。如果有,首先檢查參數溢出的可能性,確定影響範圍;

2、如果合約版本低於Solidity 0.8,需要檢查合約是否引用SafeMath;

3.如果使用SafeMath, bsc 智能合約審計 我們需要注意合約中是否有強制類型轉換,如果有,可能會有溢出的風險;

4、如果沒有使用SafeMath,並且合約中有算術運算,我們可以認為這個合約可能存在溢出風險,在實際審計中要結合實際代碼查看。

聲明:以上內容採集自VOCAL,作品版權歸原創作者所有內容均以傳遞信息為目的,不代表本站同意其觀點,不作為任何投資指導。幣圈有風險,投資需謹慎

Total
0
Shares
Related Posts