智能合約部署在區塊鏈上,例如以太坊或其他分布式賬本基礎設施,偵聽來自預言機(Oracle)的加密安全數據源的事件和更新。這些合同通常控制大量高價值數據的流動,例如轉移資金、提供服務和解鎖受保護的內容,這使它們成為極具吸引力的攻擊目標。
在設計和開發智能合約時,安全必須是重中之重。一旦智能合約部署到區塊鏈上,就很難甚至無法修補,必須刪除、重新創建和重新部署。此外,一旦智能合約上鏈,任何人都可以訪問智能合約中的漏洞。
在流行的智能合約平臺以太坊上部署用Solidity編寫的智能合約時,開發團隊需要特別注意以下九大安全漏洞(攻擊媒介):
一、重入攻擊
重入攻擊媒介的存在是因為Solidity智能合約必須執行:每一行代碼都必須在下一行代碼開始之前執行。這意味著當合約對另一個合約進行外部調用時,調用合約的執行將暫停,直到調用返回。這使被調用的合約暫時控制接下來發生的事情,從而創造了無限循環的可能性。
例如,惡意合約可以遞歸回原始合約以提取資源,而無需等待第一次調用完成,因此在函數完成之前絕不能允許原始合約更新其余額。重入攻擊有多種形式,包括單功能、跨功能、交叉收縮和只讀重入攻擊。漏洞利用列表在GitHub上維護。
修復建議:
當智能合約的代碼邏輯有缺陷時,就會出現此漏洞。開發人員需要仔細設計外部調用,并始終檢查和更新合約的狀態,例如在滿足發送資金的請求之前減少以太幣余額。添加重入防護,可鎖定協定來防止一次執行多個函數。使用各種審計工具,如Slither,Mythril和Securify,檢查是否存在不同類型的重入漏洞。
二、預言機操縱
智能合約通過預言機訪問和使用來自區塊鏈外部的數據。這使他們能夠與鏈下系統(如股票市場)進行交互。不正確的預言機數據可能會錯誤地觸發智能合約的執行,即所謂的“預言機問題”。許多去中心化金融應用程序已被這種方法利用,攻擊者最喜歡的是閃電貸款攻擊。閃電貸款本質上是無抵押貸款,只要在同一筆交易中償還貸款,就可以無限制借錢。攻擊者使用這些貸款來扭曲資產價格以產生利潤,同時仍然遵守區塊鏈的規則。
修復建議:
使用去中心化的預言機,如Chainlink或Tellor,甚至多個預言機,是確保合約收到準確數據的最簡單方法。此類預言機使攻擊者干擾數據變得更加困難和昂貴。
三、gasgriefing攻擊
要在以太坊區塊鏈平臺上執行交易或執行智能合約,用戶必須支付gas交易費,后者是為了激勵驗證者(礦工)投入驗證交易所需的資源。gas費用價格由交易時的供應、需求和網絡容量決定。
當用戶發送執行目標智能合約所需的gas量但不足以執行子調用時,就會發生gasgrief——對其他合約進行的調用。如果合約沒有檢查執行子調用所需的gas是否可用,則子調用將無法按預期執行。這可能會對應用程序的邏輯產生重大影響。
修復建議:
目前沒有有效的技術來預防gasgriefing。開發人員所能做的就是對合約進行編碼,設置要發送的gas量,而不是讓用戶來設置。然而,gas費用的上升可能意味著交易失敗。
四、交易訂單依賴攻擊(搶先)
智能合約從待處理交易提交給網絡的那一刻起就是公開可見的。這使區塊的礦工能夠選擇具有最高gas費用的交易。例如,用戶可以通過優先費–小費–以激勵礦工將他們的交易優先于同一區塊中的其他交易。然而,這也使攻擊者能夠觀察機會,他們可以通過提交相同的合同來提前運行有利可圖的合同,但gas費用更高,因為此類合同往往要求優先被處理。由于這些攻擊必須在幾分之一秒內實施,因此它們通常由機器人或礦工自己執行。
修復建議:
這些攻擊很難避免。一種選擇是只接受gas價格低于預定閾值的交易。或者使用提交和揭示方案,該方案涉及用戶首先提交解決方案哈希而不是明文解決方案,以便潛在的領跑者無法查看解決方案,直到為時已晚。各種智能合約審計工具可以檢測代碼是否引入了前端漏洞。
五、強制饋送攻擊
強制饋送攻擊利用了這樣一個事實,即開發人員無法阻止智能合約接收以太坊的原生加密貨幣以太幣。這使得以太幣轉移到任何合約中變得容易–強制喂食它們–以改變它持有的以太幣的余額,從而操縱任何僅依賴于內部會計預期余額的功能邏輯,例如如果余額增加超過一定水平,則支付獎勵。
修復建議:
以這種方式阻止合約余額操縱是不可能的。合約的余額絕不應用作函數中的檢查或保護,因為實際的以太幣余額可能高于合約內部代碼預期的余額。
六、時間戳依賴性
時間戳值由執行智能合約的節點生成。由于以太坊平臺的分布式性質,幾乎不可能保證每個節點上的時間正確同步。然后,節點可以操縱時間戳值,以針對依賴block.timestamp變量執行時間關鍵型操作的任何合約進行邏輯攻擊。
修復建議:
為避免此漏洞,開發人員不應將block.timestamp函數用作控件或邏輯檢查,或用作隨機性源。
七、拒絕服務
與任何在線服務一樣,智能合約容易受到DoS攻擊。通過重載服務(如身份驗證),攻擊者可以阻止其他合約執行或生成意外的合約還原,例如,返回未使用的gas,并且所有狀態都恢復到交易開始執行之前的狀態。這可能導致拍賣結果或金融交易中使用的價值縱以利于攻擊者。
修復建議:
使攻擊者付出高昂的代價是阻止它們的最佳方式。時間鎖定謎題和gas費只是增加攻擊者成本的一些方法。確保僅調用受信任的合約還可以降低因DoS攻擊導致嚴重問題的可能性。
八、整數下溢和溢出
當算術運算的結果超出固定大小的值范圍時,會發生整數下溢和溢出:對于整數類型uint0,則為255到8。大于255的值溢出并重置為0,而小于0的值重置為255。這會導致合約的狀態變量和邏輯發生意外更改,并觸發無效操作。
修復建議:
從版本0.8.0開始,Solidity編譯器不再允許可能導致整數下溢和溢出的代碼。檢查使用早期版本編譯的任何合約以獲取涉及算術運算的函數,或使用庫(如SafeMath)來檢查下溢和溢出問題。
九、信息和功能暴露
任何人都可以訪問區塊鏈。機密或敏感信息不應保存到區塊鏈中,除非它被加密。智能合約中的變量和函數也可以被其他智能合約看到和訪問,這使得它們有可能被誤用或濫用。
修復建議:
開發人員應始終實施適當的訪問控制,并使用最小特權原則,通過使用Solidity的變量和函數可見性修飾符來根據需要分配最低級別的可見性,而不是更多。
智能合約漏洞的預防
智能合約代碼在部署后很難修補。開發團隊從一開始就需要整合正確的安全性,嚴格測試其邏輯和代碼執行,始終遵循智能合約安全最佳實踐。除非開發團隊中有專門的智能合約安全專家,能對每個功能進行單元測試來審核智能合約代碼的邏輯缺陷和其他漏洞,否則請用智能合約的專業審計服務來識別安全問題。
D1Net
一顆小胡椒
安全牛
安全圈
安全圈
全球網絡安全資訊
商密君
安全圈
威努特工控安全
信息安全與通信保密雜志社
黑白之道
黑白之道