新型constructor函數使用漏洞,低級錯誤不容忽視區塊鏈
WF曲速未來:近期,用VaaS平臺對以太坊鏈上智能合約進行安全審計的過程中,發現了3份合約存在新的安全漏洞。并高亮顯示。
前言:
近期,用VaaS平臺對以太坊鏈上智能合約進行安全審計的過程中,發現了3份合約存在新的安全漏洞。并高亮顯示。
此漏洞是合約構造函數constructor()使用不當從而導致Owner權限被盜。
以太坊solidity0.4.22引入了新的構造函數聲明形式constructor(),該函數引入的目的是避免編程人員在編寫構造函數時的命名錯誤 (如6月22日,MorphToken事件中“Owned”被寫成“owned”,沒有注意大小寫,使owned函數成為一個普通函數,導致任何賬戶都能調用它,更改owner變量,轉移合約所有權)。
然而,由于用戶編寫函數時習慣性的使用function進行聲明,從而導致構造函數constructor的使用引入新的漏洞。
正確的構造函數形式:constructor() public { }
錯誤的構造函數形式:function constructor() public { }
問題分析:敏感函數使用不當
上述問題合約使用的Solidity編譯器版本包含了0.4.15、0.4.23,而只有在Solidity0.4.22版本后,合約的constructor()函數才被視為構造函數的形式,并且直到下一版本才會對function constructor()的形式給出警告(注意:這里僅僅是警告,不是錯誤)。如果是使用Solidity0.4.23之前的版本,編譯器把function constructor()作為普通函數進行編譯,認為是正確的普通函數。
由于該函數不符合構造函數形式,owned合約的constructor()函數,即構造函數,將合約創建者地址賦予owner,用于后續的身份驗證。但是合約的構造函數聲明存在錯誤,將constructor()誤寫成了functionconstructor(),進而產生了安全問題。
注:msg.sender 為當前操作賬戶地址、owner為合約管理者地址
由于 functionconstructor()不是構造函數的聲明形式,這里相當于聲明了一個函數名為constructor的普通函數,可被執行多次;而constructor函數的可見性修飾符為public,可被其他賬戶地址調用并修改owner的值,盜用合約管理權限。
漏洞驗證
將問題合約在Ropsten測試鏈上使用remix編譯部署測試合約Test對該問題進行了進一步驗證,發現:
1.由于缺少構造函數,初始化 owner值為0:
2.使用remix調用constructor函數,發現交易失敗,分析后發現data字段不是constructor的函數簽名:
3.更換另一個版本的solidity編譯器,執行constructor函數,發現owner被更改,說明該漏洞存在:
執行constructor函數,發現owner被更改,說明該漏洞存在:
經對該漏洞進行分析,Owner權限過大存在的安全隱患
Owner是Solidity語言中對智能合約開發者的稱呼,owner的能力猶如集齊6顆無限寶石的滅霸,屬于超級權限。對前100基于以太坊ERC20協議智能合約(例如Bancor、Augur、MakerDAO、KyberNetwork、EnigmaMPC的智能合約)安全事件進行分析后,超級權限被盜可存在如下安全隱患:
1.隨時凍結代幣轉賬
2.任意鑄造發行新的代幣
3.銷毀任意賬戶內的代幣
4.額外增發代幣
5.停止整套交易系統運行
Owner權限如此之大,說明眾多“去中心化”的產品,實際上暗藏一個一擊必殺按鈕,掌握在開發者的手上,所有對代幣虎視眈眈的黑客或者內部人員都會想方設法奪取這個按鈕的控制權。
▲Dogecoin創始人Jackson Palmer的推特評論
如此強大的權限一旦被黑客竊取,相當于從滅霸手上搶到了無限拳套,黑客可以對依賴智能合約交易的代幣為所欲為,無論是凍結,增發,還是自毀,只需要調用合約中一個函數就可輕松實現,進而操縱整個代幣的價值。而與之相關的代幣也必將遭受沖擊,后果不堪設想。
如何避免將會導致的風險
既然合約開發者可能會存在使用constructor函數不當,那么作為項目方應該如何去防范后期可能造成的風險呢?我們給出下面兩種建議方法:
1.新的constructor使用方法為,前面無function聲明:
2.Remix-ide等編譯器會對constructor的錯誤使用產生警告,開發者千萬不要忽略編譯器告警,推薦更改源碼,消除所有編譯器警告。
問題總結
驗證結果以及各區塊鏈安全專家的意見后指出該漏洞導致的后果可能有:
1.合約可被普通用戶竊取owner權限;
2.目前很多ERC20代幣部署的時候將所有代幣發放到owner賬戶中,如果出現此漏洞,可導致用戶無限增發代幣;
以及更多取決于owner權限的嚴重后果(也許就像滅霸打一個響指,代幣灰飛煙滅)。
此次owner權限漏洞雖然來源于代碼編寫上的低級錯誤,但更多的是引起開發者對owner權限問題的反思,過于神化的owner權限必然導致owner權限漏洞成為眾矢之的,而低級錯誤導致的此類漏洞是絕不應該出現的。
區塊鏈安全公司WF曲速未來再次提醒項目方,開發者書寫合約敏感函數(如構造函數、回調函數)時,應嚴格遵循官方命名要求,并重視編譯器提出的警告。同時,合約在發布到主鏈前,開發者應在官方提供的測試網絡上進行充分驗證,從多角度分析合約代碼,找出那些容易忽略的問題,并且做到防患于未然。
1.TMT觀察網遵循行業規范,任何轉載的稿件都會明確標注作者和來源;
2.TMT觀察網的原創文章,請轉載時務必注明文章作者和"來源:TMT觀察網",不尊重原創的行為TMT觀察網或將追究責任;
3.作者投稿可能會經TMT觀察網編輯修改或補充。