【鏈必驗】智能合約自動檢測工具,可用來檢測區塊鏈智能合約漏洞。平台針對每個用戶模擬了一條單獨的測試鏈,用戶可以自主在測試鏈上對智能合約進行部署、測試和驗證,是集智能合約开發、測試、驗證於一體的綜合平台。
在驗證的過程中,平台採用形式化驗證等技術,對執行環境進行建模,通過數學推理等方法對安全屬性進行驗證,發現合約在運行時可能出現的安全問題,協助合約开發者發現合約中的潛在安全隱患,定位漏洞產生的位置,增強合約的安全性。主要包含四大方面的檢測:代碼規範檢測、標准規範檢測、函數調用檢測、業務邏輯安全檢測。
Web3.0世界,最不可或缺的,便是智能合約。今天,跟着我們一起來學習這款智能合約自動檢測工具,一起解鎖Web3.0世界。
等級:ERROR
描述:0.4.7-0.5.9版本solc編譯器存在一個BUG,此BUG會導致abi.encode接口處理多維數組時產生錯誤結果。
樣例
在編譯器版本爲0.5.9時,嵌套數組badArr的返回值是錯誤的,爲 [[1, 2], [2, 3], [3, 4]]。在編譯器版本爲0.6.7時,嵌套數組badArr的返回值是正確的,爲 [[1, 2], [3, 4], [5, 6]]。
修復建議:避免使用0.4.7-0.5.9編譯器,或禁止使用0.4.7-0.5.9編譯器中的abi.encode接口。
等級:ERROR
描述:在0.4.22版本的編譯器中,合約允許合約同時存在兩個格式的構造函數(以constructor關鍵字聲明構造函數,或以合約名聲明函數)。因此構造函數中的變量存在相互覆蓋的危險。
樣例
constructor()中初始化x爲1,而Test()初始化x爲2,位置靠後定義的構造函數會失效,因此x最終會被初始化爲1。
修復建議:只使用一種構造函數。
等級:ERROR
描述:公开的變量有一個默認的只讀getter函數,但公开的mapping嵌套引用結構將導致非法的getter函數。
樣例
公开的mappingm嵌套了引用類型struct,將導致針對public變量的默認的讀取方法m[1].a失敗。
修復建議:避免使用public mapping嵌套引用類型,或者使用pragma experimental ABIEncoderV2。
等級:ERROR
描述:Unicode [U+202E] 強制編譯器從右到左讀取,與正常順序相反,可能誤導使用者。
樣例
_f函數期待輸入值i,j,m依次傳遞給a,b,c由於有U+202E的存在,輸入函數需要以j,i,m的順序給出。
修復建議:避免使用U+202E字符。
等級:ERROR
描述:合約的繼承包括狀態變量的繼承,在子合約中重載基類合約的狀態變量可能會造成變量的使用邏輯錯誤。
樣例
合約Test是Base的子合約,Test中a的定義重載了Base中的狀態變量a。調用f1()將返回Base中的a,調用f2()將返回Test中的a。
修復建議:避免重載基類合約狀態變量。
等級:ERROR
描述:未初始化的storage狀態變量的地址將指向第一個狀態變量的地址,使用它可能造成數據覆蓋或數據丟失。
樣例
未初始化變量st的存儲指針將指向狀態變量a,st.b的賦值將覆蓋變量a使a的值變爲2。
修復建議:使用前先初始化storage局部變量,或改用memory局部變量。
等級:WARNING
描述:在Solidity 0.5.0之前,其可變性被定義爲constant/prue/view的函數,但更改了函數體中的語句。這樣的函數可以編譯,但是只報warning,進一步調用該函數會失敗。這個問題在0.5.0以後的版本中已經修復,常量函數中實現的狀態修改無法編譯。
樣例
變量a在f()函數中改變了它的值,但是a()函數被標記爲view。所以調用 f() 不會改變 a。
修復建議:確保Solidity 0.5.0之前的合約的可變性是正確的。
等級:WARNING
描述:使用delete重置包含mapping的struct時,struct中的mapping不會被重置,這可能導致後續邏輯錯誤。
樣例
合約在初始化後實例化了一個struct a,並將a.i初始化爲10以及a.j[10]初始化爲100。在f1中使用delete a重置了結構a。f2()中可以讀取數據,結果是變量a.i已經被重置爲0,但是a.j[10]中的數據仍然是100。
修復建議:避免使用delete重置包含mapping的struct。
等級:WARNING
描述:在returns語句中聲明了返回名稱及類型,但實際返回值與聲明中變量不符。
樣例
函數f()定義了一個返回類型和名稱爲uint a,而return語句直接返回100,與return聲明不匹配。
修復建議:確保return語句中的值與returns語句中的返回聲明相匹配。
等級:WARNING
描述:合約之間允許繼承,子合約繼承父合約的狀態變量、函數、構造函數。當子合約繼承了多個構造函數時,可能多次重用構造函數。
樣例
Test1和Test2都是繼承了合約test的子合約,並重用了構造函數將各自的狀態變量a初始化爲1和2,合約Test3繼承了合約Test1和Test2,因此具有兩個不同的構造函數,導致Test3中狀態變量a被多次賦值,並最終賦值爲2。
修復建議:確保子合約擁有唯一繼承的構造函數。
等級:ERROR
描述:當合約定義ERC20標准的transfer/transferFrom接口時,需要檢查transfer/transferFrom接口的返回值,否則會導致對轉账狀態的判斷錯誤。
樣例
token.transferFrom(msg.sender, address(this), amount);的返回值需要檢驗。
修復建議:對所有轉账函數的結果進行校驗。
等級:WARNING
描述:在定義標准的ERC20接口時與標准ERC20接口不完全一致。
樣例
ERC20標准的Transfer事件是event Transfer(address indexed from, address indexed to, uint256 value);。
修復建議:完全參照ERC20標准設置ERC20事件和接口。
等級:WARNING
描述:定義的標准ERC721接口和標准ERC721接口並不完全相同。
樣例
函數ownerOf(uint256 tokenId)是ERC721的接口,但缺少參數或返回值。
修復建議:對照ERC721
等級:ERROR
描述:委托調用是調用合約的一種方式。委托調用的操作空間在調用發起這一方,因此沒有任何權限控制或調用地址未知的調用是可被入侵的。
樣例
addr可以被調用者任意操控。
修復建議:爲執行delegatecall所在函數設置權限控制,指定調用者。
等級:ERROR
描述:智能合約的底層調用具有返回數據,調用合約執行失敗不會導致調用發起合約執行失敗,如果調用操作失敗且沒有檢查返回值,可能導致預計邏輯與實際狀態出現差異。
樣例
address(f).call(abi.encodePacked(function_selector)); 實現了對合約Base中函數f()的調用。但是使用了call沒有對調用的返回值做校驗,將導致無法判斷調用狀態。
修復建議:對所有底層call方法返回值進行校驗。
等級:ERROR
描述:智能合約的轉账函數send具有返回值,如果轉账失敗代碼會繼續執行,調用不會回退狀態。因此使用send進行轉账時應檢查返回值,並以此判定轉账是否成功。
樣例
函數f使用send進行轉移ether,由於沒有對send的返回值進行校驗,將不能知曉轉账是否真實成功。
修復建議:使用send進行轉账時,對返回值進行校驗。
等級:INFO
描述:使用低級調用是有風險的。低級調用不檢查代碼是否存在或調用成功。
修復建議:避免底層call
等級:ERROR
描述:轉账函數沒有添加任何權限限制,且轉账接受者可設定,任何人都可以獲取合約資金。
樣例
函數f()沒有任何權限控制,且轉账接受者是msg.sender。調用f()即可獲得合約所有資金。
修復建議:當合約存在對外轉账功能時,對包含轉账函數添加正確的權限控制。
等級:ERROR
描述:在solc 0.6.0版本以下,動態數組類型的長度信息可以被直接修改,長度信息的改變將直接影響存儲的數組數據。
樣例
合約部署後,動態數組a的第20位數據a[20]爲1,若調用f(10)將a的長度修改爲10,則a[20]指向的值將丟失。
修復建議:避免對動態數組的長度直接或間接修改。
等級:ERROR
描述:在0.4.5版本以前,枚舉類型的調用不會進行溢出判斷。
樣例
E是長度爲3的enum類型,即使嘗試讀取E的第10個,bug()函數也不會恢復。
修復建議:避免使用0.4.0-0.4.4版本的solc編譯器,或對枚舉值進行區間判斷。
等級:ERROR
描述:在智能合約中存在收取以太幣的函數,但不存在發出幣的函數,將導致以太幣被鎖定在合約中。
樣例
函數f()有一個payable符號,但合約沒有能力花費/轉移以太幣。
修復建議:移除收錢函數的payable屬性,或添加可消耗Ether/向外轉Ether的函數。
等級:ERROR
描述:修飾器起到一個狀態/權限控制的作用,在修飾器中如果無法到達_;代碼段,將無法執行函數並引起邏輯錯誤。
樣例
修飾符 bug1() 有一個 if 語句,當bool_test 爲 false 時, _; 不會到達,那么函數 use() 將不會被使用。
修復建議:保證修飾器可以到達_;代碼段,正確執行修飾器功能。
等級:ERROR
描述:在函數返回聲明有返回值,但沒有相應的返回實現。
樣例
函數f()聲明返回一個uint類型的值,而合約在函數體中缺少return關鍵字,這將導致返回0(uint類型的最小值 )。
修復建議:添加對應的返回值或刪除返回聲明。
等級:ERROR
描述:調用外部合約的主要危險之一是它們可以接管控制流。在重入攻擊(又名遞歸調用攻擊)中,惡意合約在函數的第一次調用完成之前回調調用合約。這可能會導致函數的不同調用以不希望的方式交互。在call調用後改變關鍵狀態變量容易造成重入危險。
樣例
在函數f()判斷地址擁有的數額大小後,使用call發送以太幣,最後storage變量book在轉账操作後發生變化。因此,攻擊者可以循環調用f()來提取以太幣。
修復建議:使用檢查-生效-交互模式避免重入攻擊。
等級:ERROR
描述:合約中包含了自毀函數,且沒有使用任何身份認證,將使合約處於不穩定狀態。
樣例
任何人都可以通過調用f()將合約銷毀並提取合約中的資金。
修復建議:盡量避免使用自毀函數,或添加正確的權限控制。
等級:ERROR
描述:在合約的構造函數中存在未初始化的函數指針,直接調用這些指針將出現錯誤。
樣例
f是constructor中的函數指針,而在函數指針完全實現之前,它已被調用。這種行爲會導致部署失敗。
修復建議:在函數指針完全實現之前不要調用函數指針。
等級:ERROR
描述:使用未初始化的狀態變量可能導致邏輯錯誤。
樣例
狀態變量a未初始化,將被默認爲0地址。在執行轉账操作時,將導致以太幣丟失(轉账去0x0地址)。
修復建議:盡可能在聲明狀態變量時便初始化該狀態變量。
等級:ERROR
描述:合約包含自毀函數,且初始化函數任何人可調用。
樣例
函數initialize()會初始化合約,但任何人都可以調用,如果攻擊者在所有者之前調用initialize(),攻擊者可以隨時調用kill()來使代理合約功能失效。
修復建議:在合約中將初始化函數功能在構造函數中執行,保證owner不能任意修改。
等級:ERROR
描述:assert的限制條件是必須滿足的。
修復建議:請查看代碼邏輯尋找問題並修復。
等級:ERROR
描述:上溢出是指運算的結果超過了結果類型所能表示的上限。
修復建議:請加上溢出判斷或使用SafeMath庫進行運算。
等級:ERROR
描述:下溢出表示計算操作中的結果超過了結果類型可以表示的下限。
修復建議:請加下溢出判斷或使用SafeMath
以上只選取一些案例
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播信息之目的,不構成任何投資建議,如有侵權行為,請第一時間聯絡我們修改或刪除,多謝。
標題:如何用智能合約自動檢測工具解鎖Web3.0世界
地址:https://www.torrentbusiness.com/article/1453.html
標籤: