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