WF曲速未來:Solidity安全之默認可見性(Visibility)區(qū)塊鏈
WF曲速區(qū):Soildity作為編寫智能合約的語言,已經被廣泛的應用。但同時,開發(fā)者和用戶也得到了慘痛的教訓,智能合約的安全問題層出不窮。因此,我們總結了一些常見的Solidity安全問題。前車之鑒,后車之師,希望后來者能有所警惕。
Soildity作為編寫智能合約的語言,已經被廣泛的應用。但同時,開發(fā)者和用戶也得到了慘痛的教訓,智能合約的安全問題層出不窮。因此,我們總結了一些常見的Solidity安全問題。前車之鑒,后車之師,希望后來者能有所警惕。
默認可見性(Visibility)
Solidity有兩種函數調用方式,一種是內部調用,不會創(chuàng)建一個EVM調用(也叫做消息調用),另一種則是外部調用,會創(chuàng)建EVM調用(會發(fā)起消息調用)。其中的函數具有可見性說明符,它們會指定我們可以如何調用函數。可見性決定一個函數是否可以由用戶或其他派生契約在外部調用、只允許內部調用或只允許外部調用。Solidity對函數和狀態(tài)變量提供了四種可見性。分別是external,public,internal,private。為允許用戶從外部調用函數,其中函數默認可見性默認為public。而本文將介紹的是可見性說明符的不正確使用會導致智能合約中的一些資金流失的問題。
代碼分析
函數的可見性默認是 public。因此,不指定任何可見性的函數就可以由用戶在外部調用。當開發(fā)人員錯誤地忽略應該是私有的功能(或只能在合約本身內調用)的可見性說明符時,問題就出現了。
讓我們看一個簡單的例子。
這個簡單的合約被設計為充當賞金猜測游戲的地址。要贏得該合約的余額,用戶必須生成一個以太坊地址,其最后 8 個十六進制字符為0。一旦獲得,他們可以調用 WithdrawWinnings() 函數來獲得賞金。不幸的是,這些功能的可見性沒有得到指定。特別是,因為_sendWinnings() 函數的可見性是 public,任何地址都可以調用該函數來竊取賞金。
相關事件
我們昨天在前一篇介紹Delegatecall函數濫用問題中引用了Parity錢包被黑事件,默認可見性也是攻擊者在這次事件中利用的漏洞之一。接下來我們詳細的分析攻擊者的利用過程:
先看看Parity錢包的合約,有兩個,其一是庫合約,第二是錢包合約。
庫合約包含初始化錢包的代碼,如以下代碼片段所示
在合約中,initWallet() 與initMultiowned()兩個函數的可見性都默認為 public 。錢包構造函數會調用 initWallet() 函數,并設置多簽名錢包的所有者,如 initMultiowned() 函數中所示。由于這些函數意外地設置為 public,攻擊者可以在部署的合約上調用這些功能,并將所有權重置為攻擊者地址。作為主人,襲擊者隨后取走錢包中所有的 Ether,損失高達 3100 萬美元。
區(qū)塊鏈安全公司WF曲速未來 觀點:
指定合約中所有功能的可見性、即便這些函數的可見性本就有意設計成 public,這是一種很好的做法。最近版本的 Solidity 將在編譯過程中為沒有明確設置可見性的函數顯示警告,以鼓勵這種做法。所以人們在編寫智能合約時應注意函數可見性說明符的正確使用。
1.TMT觀察網遵循行業(yè)規(guī)范,任何轉載的稿件都會明確標注作者和來源;
2.TMT觀察網的原創(chuàng)文章,請轉載時務必注明文章作者和"來源:TMT觀察網",不尊重原創(chuàng)的行為TMT觀察網或將追究責任;
3.作者投稿可能會經TMT觀察網編輯修改或補充。