近期,有人發現並報道了ERC20標準的approve方法存在巨大安全漏洞,並聲稱該漏洞會導致所有使用該標準釋出的代幣存在被向量攻擊的風險。
該團隊經過市場統計發現,目前已上交易所的數字貨幣中至少有超過60%的幣種,在智慧合約中使用了存在該漏洞的程式碼。
該漏洞作為以太坊標準導致的重大安全隱患,已經被該團隊命名為“jaeden”,並且已經提交到cve平臺。
有人釋出ERC20存在巨大安全漏洞
緊接著,慢霧科技、Hashgard等團隊對此給予明確的回覆:均認為是虛驚一場。
慢霧的回覆(釋出於知識星球-慢霧區,作者:餘弦)
Hashgard團隊的官網回覆
成都鏈安科技一直都非常重視智慧合約安全問題,鑑於行業對該“重大漏洞”的分歧,為了使廣大智慧合約開發者,以及區塊鏈從業者能夠更多的瞭解該問題,我們也專門針對此問題進行了深入分析和探討,並且給出我們的解決辦法,便於大家寫出更安全的智慧合約。
到底什麼是「jaeden漏洞」?
首先,我們來看看approve函式是如何使用的:
從程式碼中我們可以看到:以太坊ERC20代幣標準,可以用approve函式來授權第三方賬戶使用指定額度的代幣。然後,第三方賬戶便可以透過使用transferfrom函式來使用授權給自己賬戶的代幣。
那麼,approve函式為什麼就可能會造成一定安全隱患呢?因為在區塊鏈交易過程中,對於間隔時間很短的交易,使用者廣播訊息gas的數量不同,會直接影響交易打包到區塊的先後順序,gas多的訊息會被優先執行。區塊鏈交易過程圖如下:
舉個簡單的例子:使用者A使用approve授權給使用者B使用100代幣額度,後來使用者A要改變授權額度為50代幣。在更改授權之前,使用者A查詢使用者B是否使用了授權額度的代幣,如果查詢到B並沒有使用之前的額度,則透過approve函式重新授權給使用者B新的50代幣的額度。
以上過程僅為使用者A的操作,於此同時,使用者B同樣可以進行相關操作:
使用者A查詢使用者B授權的使用情況,確定使用者B沒有使用授權代幣後,使用者A發出更改授權額度交易,但在更改交易成功之前,使用者B可利用區塊鏈打包訊息的機制,發起一個gas數量很大的從使用者A轉賬100代幣的交易。
由於使用者B發出的交易gas數量大於使用者A更改授權額度交易的gas數量,因此礦機先執行使用者B的交易,於是使用者B將搶先在使用者A更改授權額度交易生效之前轉走了使用者A上次授權的100代幣。從而,等到礦機執行了修改50額度的交易後,使用者B又可以使用新授權的50代幣。
所以,使用者A、B上述授權和轉賬的操作過程將可能產生兩種結果:
使用者A成功的實現了授權額度的更新,使用者B只能使用使用者A授權的50代幣;
使用者B得到兩次次授權,可以使用150代幣。
因此,使用者在使用approve重新授權過程中可能導致兩種不同的執行結果,存在造成多次授權的可能性。
如何規避「jaeden漏洞」?
那麼,既然存在多次授權的隱患,那麼有沒有規避的辦法呢?
答案是:有的,我們針對此問題,給出下面兩種規避的方法。
第一,在更改授權之前,可先透過approve函式設定授權代幣數量為0。等到授權為0操作成功後,並查詢被授權的使用者沒有使用過原授權代幣,再透過approve函式重新設定授權代幣數量,就可以避免多次授權。
第二,建議代幣智慧合約開發使用increaseApproval和decreaseApproval函式,進行授權更改操作。該功能直接在授權代幣數目上面做增減操作,以避免上述問題。
不算漏洞的漏洞
經過上文的分析,我們認為,將此問題歸結為安全的“重大漏洞”有點誇大,其本質是區塊鏈交易過程的排隊機制會造成插隊現象,從而引起了操作結果的不唯一性。
在使用者本身不做多次授權更改的情況下,是不會造成相關問題的。另外,即使使用者需要做多次授權,也有技術方法規避該類情況的發生。
此外,我們對於最近有人報道的關於鑄幣函式Mint的高危漏洞問題,也進行了分析,我們認為mint函式不一定導致惡意增發。我們對以太坊市值Top 500的代幣合約進行了審計,發現有107個合約使用的mint函式,可使代幣發起方實現代幣的無限增發。
我們將此情況與交易所進行了及時反饋,透過跟專案方和交易所的溝通發現,並不是所有的鑄幣函式都是高危漏洞,有的合約使用該函式是因為代幣發起方專案必不可少的功能需求。當然,也不排除有的專案方會利用該函式惡意增發的可能。
關於作者:
楊霞,成都鏈安科技CEO,創始人。電子科技大學副教授,最早研究區塊鍊形式化驗證的專家。一直為航空航天、軍事領域提供形式化驗證服務。主持國家核高基、裝發重大軟體課題等近10項國家課題。CC國際安全標準成員、CCF區塊鏈專委會委員。發表學術論文30多篇,申請20多項專利。