岳勇 郭仲勇 艾陽
摘 要:隨著區(qū)塊鏈技術(shù)應(yīng)用范圍越來越廣泛,也面臨著諸多方面的安全威脅,智能合約引發(fā)的安全問題已經(jīng)成為區(qū)塊鏈安全性的主要問題。本文通過對智能合約安全性分析,提出相應(yīng)的解決方案;通過合約安全審計方法、合約安全監(jiān)測工具等措施對智能合約進行安全管理,保障信息系統(tǒng)安全。
關(guān)鍵詞:區(qū)塊鏈;智能合約;隱私保護;安全漏洞;安全審計
中圖分類號: TP309
0 引言
智能合約是部署在區(qū)塊鏈上的代碼,利用協(xié)議和用戶接口完成合約過程。在智能合約層,通過在智能合約上添加能夠與用戶交互的前臺界面,并能與其它外部IT系統(tǒng)進行數(shù)據(jù)交互和處理,形成去中心化的應(yīng)用(DAPP),實現(xiàn)各種行業(yè)應(yīng)用。智能合約具有事件驅(qū)動、自動執(zhí)行及價值轉(zhuǎn)移等特點,通過智能合約處理各種事務(wù),減少了人為干預(yù)的風險,能夠在任何時刻響應(yīng)用戶需求,這樣能夠大大提升效率,節(jié)約時間和成本。由于智能合約整體處于初期階段,需要重視其安全性、擴展性、以及與現(xiàn)實世界的法律體系的對接等問題,尤其是安全性問題得不到有效解決,將會嚴重阻礙價值互聯(lián)網(wǎng)的推進步伐。
1? 技術(shù)原理
1.1? 智能合約的執(zhí)行環(huán)境
目前以太坊和超級賬本的智能合約技術(shù)相對更為成熟,在以太坊中合約代碼在虛擬機中執(zhí)行,超級賬本中合約代碼在容器中執(zhí)行。虛擬機和容器都創(chuàng)造了一個封閉的沙箱環(huán)境,在封閉隔離的情況下執(zhí)行合約代碼。
以太坊虛擬機是一種圖靈完備的,基于棧的后進先出特性設(shè)計的虛擬機,它可以將智能合約代碼編譯成可以在以太坊上執(zhí)行的機器代碼,并為智能合約提供一個完全封閉的運行環(huán)境,在以太坊中每個節(jié)點都創(chuàng)建了一個EVM虛擬機,當出現(xiàn)調(diào)用合約交易時,所有節(jié)點都會執(zhí)行一遍合約并對結(jié)果進行共識。
超級賬本采用了容器(docker)作為智能合約的執(zhí)行環(huán)境,和虛擬機相比容器沒有采用虛擬化技術(shù),而是直接運行在底層操作系統(tǒng)上之上,因此在容器中合約的執(zhí)行效率很高。但相較于虛擬機而言,容器的啟動和執(zhí)行過于消耗資源,這也成為了制約超級賬本性能的關(guān)鍵因素。
1.2 智能合約的運行機制
在一個智能合約內(nèi)一般包含合約值和合約狀態(tài)兩個屬性, 在智能合約代碼中寫明了合約的應(yīng)用場景和觸發(fā)規(guī)則, 一旦外部輸入數(shù)據(jù)符合觸發(fā)條件,可以就會開始執(zhí)行并返回相應(yīng)的結(jié)果。如下圖1所示,由于區(qū)塊鏈種類及運行機制的差異,不同平臺上智能合約的運行機制也有所不同。智能合約的生命周期可以簡單的分為開發(fā)、部署、執(zhí)行三個階段。
(1)開發(fā)階段:合約開發(fā)階段,主要是由多方協(xié)商,根據(jù)現(xiàn)實世界的合同規(guī)則編寫相應(yīng)的程序代碼,編寫過程中需要開發(fā)者熟悉合約代碼的編寫思維,盡可能簡潔以防止代碼出錯。
(2)部署階段:合約開發(fā)完成后,發(fā)起方用戶對合約簽名并發(fā)起一條交易,交易經(jīng)過網(wǎng)絡(luò)廣播和節(jié)點驗證后,跟這一時間戳內(nèi)的其他交易一同保存在當前區(qū)塊中,合約部署成功后將返回合約地址和相關(guān)接口信息,用戶可以通過合約地址和接口信息對部署成功的合約進行調(diào)用。
(3)執(zhí)行階段:調(diào)用合約需要用戶通過合約地址和接口信息發(fā)起交易,區(qū)塊鏈內(nèi)的其他節(jié)點為了獲得系統(tǒng)預(yù)設(shè)的獎勵會幫助新區(qū)塊的產(chǎn)生。節(jié)點收到調(diào)用合約的相關(guān)交易后將在一個本地沙箱環(huán)境中執(zhí)行合約(如以太坊虛擬機EVM),執(zhí)行過程中,合約代碼根據(jù)外部輸入數(shù)據(jù)和合約狀態(tài)信息判斷當前合約狀態(tài)是否滿足合約觸發(fā)條件以執(zhí)行合約內(nèi)的操作,符合條件的更新操作,在經(jīng)過共識算法的驗證后會進入?yún)^(qū)塊鏈新的區(qū)塊中。
2? 智能合約安全性分析
智能合約的安全性通常可以從代碼編寫、合約虛擬機和區(qū)塊鏈特性這三個維度展開,以下分別對這三個方面的安全性漏洞進行了分析,針對其中可能出現(xiàn)的問題也提出了相應(yīng)的解決方案。
2.1? 合約隱私泄露
即使在聯(lián)盟鏈中,由于區(qū)塊鏈交易信息公開,合約代碼完全開源,合約從創(chuàng)建、部署到執(zhí)行的整個過程都會被廣播到參與聯(lián)盟鏈的全部節(jié)點,導(dǎo)致合約參與者的真實身份有很大可能會被有意的攻擊方識破。一些機密合約的隱私內(nèi)容,有時不便公開,如果依然采用原先的部署、執(zhí)行方式,將導(dǎo)致合約參與者的重要信息受到威脅。
解決方案:
(1) 采用盲簽名。盲簽名技術(shù)即簽名者在不知道所簽文件內(nèi)容的情況下進行簽署,而發(fā)送者卻可以從簽名者對盲化后的文件簽名中提取出有效簽名,這體現(xiàn)了盲簽名技術(shù)所具有的盲性和不可偽造性的特點。
(2)采用環(huán)簽名。環(huán)簽名是一種簡化的類群簽名,它是指環(huán)中的成員用他自己的私鑰和其他環(huán)成員的公鑰進行簽名,這一過程并不需要征得其他成員的同意,簽名的驗證者可以知道簽名來自這個環(huán),但無法定位準確的環(huán)成員,這也是一種對合約參與者身份安全的保護方式。
(3)采用同態(tài)加密。同態(tài)加密是一種特殊的加密方法,對密文進行數(shù)據(jù)處理得到的結(jié)果跟對明文進行數(shù)據(jù)處理再加密的結(jié)果相同,即同態(tài)性。在區(qū)塊鏈上應(yīng)用同態(tài)加密技術(shù)可以對公開的數(shù)據(jù)進行加密,再進行數(shù)據(jù)處理,這種方式可以在保證區(qū)塊鏈信息公開的情況下保證信息安全。
(4)采用零知識證明(ZKPs)。 零知識證明是指證明者在不向驗證者提供任何有用信息的情況下證明某個事件是真實的,即可以在不泄露數(shù)據(jù)本身情況下證明某些數(shù)據(jù)運算。在區(qū)塊鏈中使用零知識證明技術(shù)可以在不泄露交易數(shù)據(jù)的情況下證明交易已經(jīng)正確完成。
2.2? 合約主體漏洞
智能合約的代碼編寫不同于以往的項目開發(fā),智能合約在部署后一旦出現(xiàn)問題,所付出的代價是巨大的,對于多種區(qū)塊鏈來說都難以簡單的解決,因此我們在編寫合約代碼時要提升安全思維,做好安全準備。
2.2.1函數(shù)可重入性
智能合約執(zhí)行過程中當一個合約調(diào)用另一個合約時,當前的執(zhí)行過程會暫停等待另一個合約的返回值。這會導(dǎo)致一個很嚴重的問題,如果程序可以在執(zhí)行過程中被中斷,則可以在其先前的調(diào)用完成執(zhí)行之前安全地再次調(diào)用,這被稱為可重入計算機程序。在調(diào)用其他外部函數(shù)的操作完成前,這個被調(diào)用的函數(shù)很有可能會被多次執(zhí)行,這種多次調(diào)用可能會造成難以想象的問題。
解決方案:
避免外部調(diào)用:調(diào)用外部合約的函數(shù),造成等待返回結(jié)果這種情況,很容易引發(fā)重入問題,外部合約中還可能會有其他惡意代碼、安全威脅,在編寫合約代碼時應(yīng)該盡量少的調(diào)用外部合約。
處理外部調(diào)用錯誤:在調(diào)用外部合約時,需要注意調(diào)用函數(shù)的返回值,當出現(xiàn)異?;蚍祷劐e誤結(jié)果時一定要針對返回的錯誤結(jié)果進行及時處理。
合約狀態(tài)檢查:有效防止函數(shù)重入的另一種方法是在合約代碼需要進行外部調(diào)用之前更新狀態(tài)并在合約中檢查,以確保當前狀態(tài)代表接下來會執(zhí)行的事務(wù)。
2.2.2 函數(shù)可見性
以Solidity為例,在使用Solidity編寫合約代碼時,共提供了4種函數(shù)可見性修飾符,在開發(fā)者沒有指明的情況下,默認為public。當開發(fā)者沒有明確指明函數(shù)可見性時,可能導(dǎo)致部分關(guān)鍵函數(shù)的可見性為公開的,這使得任何外部用戶都可以調(diào)用這一函數(shù),可能會造成巨大損失。
解決方案:在編寫合約代碼時,明確指明函數(shù)可見性,以免造成意想不到的損失。
2.2.3 誤操作異常
在以太坊中,允許一個合約通過send指令或者直接調(diào)用的方式去調(diào)用另一個合約內(nèi)的函數(shù)。然而在調(diào)用過程中可能會出現(xiàn)錯誤,例如gas不足、超出調(diào)用棧限制,調(diào)用就會終止,合約就會回退到之前的狀態(tài)。調(diào)用者很可能并未獲知調(diào)用過程中出現(xiàn)的異常,這主要取決于調(diào)用的方式。使用這條指令調(diào)用合約后,必須檢查返回值驗證合約是否正確執(zhí)行。根據(jù)數(shù)據(jù)統(tǒng)計,現(xiàn)有合約中約28%的合約在調(diào)用后不會檢查異常返回值,這在一定程度上會造成許多問題。
解決方案:
避免使用不檢查異常和錯誤返回值的調(diào)用方式,針對可能出現(xiàn)的錯誤情況,做好錯誤處理和返回值檢查。
2.3 虛擬機安全漏洞
合約虛擬機運行在區(qū)塊鏈的各個節(jié)點之上,虛擬機為合約代碼提供了一個沙箱式的執(zhí)行環(huán)境,如果合約虛擬機存在漏洞或不完善的地方,則很由可能會受到攻擊者的攻擊,虛擬機系統(tǒng)相比較于傳統(tǒng)的計算機運行環(huán)境具有更多的攻擊安全隱患,以下列出常見的幾種:
(1)逃逸漏洞:虛擬機在運行中,一般進程只能在沙盒的限制中執(zhí)行相應(yīng)的代碼,逃逸漏洞指的是進程越過虛擬機范圍,進入到宿主機的操作系統(tǒng)中,這種漏洞會使攻擊者退出沙盒環(huán)境,執(zhí)行其他本不能執(zhí)行的代碼。
(2)邏輯漏洞:虛擬機在發(fā)現(xiàn)數(shù)據(jù)或代碼不符合規(guī)范時,可能會對數(shù)據(jù)做一些“容錯處理”,這就導(dǎo)致可能會出現(xiàn)一些邏輯問題,最典型的是“以太坊短地址攻擊”。
(3)堆棧溢出漏洞:虛擬機的調(diào)用棧有確定的最大深度,在一些攻擊者的惡意調(diào)用下,有可能導(dǎo)致棧的深度超過虛擬機允許的最大深度,或不斷占用系統(tǒng)內(nèi)存導(dǎo)致內(nèi)存溢出。
(4)資源濫用漏洞:指的是攻擊者在虛擬機中執(zhí)行惡意代碼,估計消耗系統(tǒng)的網(wǎng)絡(luò)資源、存儲資源、計算資源、內(nèi)存資源。所以在虛擬機系統(tǒng)中必須要有一些限制機制來防止系統(tǒng)的資源被濫用。
解決方案:
1、為虛擬機設(shè)置安全域和安全域之間的訪問規(guī)則,如果虛擬機有添加或刪除等破壞規(guī)則的操作時則刪除該虛擬機所屬的網(wǎng)絡(luò)。
2、為區(qū)塊鏈虛擬機,設(shè)計一種安全監(jiān)測機制,這項機制可以做到對資源的收集、分析和監(jiān)測,根據(jù)實時獲取到的虛擬機信息對有異常情況的虛擬機進行處理。
3、采用基于大數(shù)據(jù)與機器學(xué)習的虛擬機安全防護方法,從虛擬機的中提取文件,接著識別普通文件中的惡意特征,將識別的惡意特征與惡意文件特征庫中的特征進行比對,判斷該文件是否為惡意文件,若為惡意文件則進行清理。
4、采用于KVM虛擬機系統(tǒng)的安全防護方法,可以周期性地獲取虛擬機系統(tǒng)的中斷描述符表、系統(tǒng)調(diào)用表和系統(tǒng)調(diào)用數(shù)據(jù),將獲取到的虛擬機系統(tǒng)中的數(shù)據(jù)與備份的相應(yīng)數(shù)據(jù)進行比較,當發(fā)現(xiàn)異常時用備份的數(shù)據(jù)對虛擬機系統(tǒng)中狀態(tài)異常的內(nèi)核對象進行恢復(fù)。
2.4 區(qū)塊鏈特性導(dǎo)致的漏洞
2.4.1交易順序依賴
在區(qū)塊鏈中一個區(qū)塊包含多條交易,而一筆交易從被廣播出去到被確認并包含在一個區(qū)塊內(nèi)需要一定的時間。我們假設(shè)有一個區(qū)塊鏈目前處于狀態(tài)σ,新區(qū)塊中包括兩條調(diào)用相同合約的交易(deg:Ti,Tj),在這種情況下,用戶無法確定合約在執(zhí)行調(diào)用時是什么狀態(tài)。當合約處于σ[Ti]時執(zhí)行Tj的調(diào)用和處于σ[Tj]時執(zhí)行Ti的調(diào)用可能會造成截然不同的結(jié)果,這取決于Ti和Tj之間的順序,而只有挖掘這一區(qū)塊的節(jié)點才能決定這些交易的順序,從而決定合約被調(diào)用的順序。如果有攻擊者在監(jiān)聽到網(wǎng)絡(luò)中對應(yīng)合約的交易后,發(fā)出他自己的交易來改變當前的合約狀態(tài),則有一定幾率使這兩筆交易包含在同一個區(qū)塊下面,并且有可能排在另一個交易之前,完成攻擊。合約的最終狀態(tài)實際上取決節(jié)點在確認時的交易順序, 我們將此類合約稱為交易依賴合約或TOD合約。
解決方案:
針對交易順序依賴,開發(fā)者對于交易的獎勵機制要進行合理的設(shè)置,以防止通過調(diào)整獎勵金額來改變交易決定順序的情況出現(xiàn),對于一些關(guān)鍵事務(wù)的交易頻率要做限制,防止短時間內(nèi)大量交易出現(xiàn)。
2.4.2 時間戳依賴
另一個很重要的安全問題是,合約有時會用區(qū)塊時間戳作為執(zhí)行一系列關(guān)鍵操作的觸發(fā)條件。我們把這樣的合約稱為時間戳依賴合約,在許多合約游戲中都會使用隨機數(shù)來決定誰贏得頭獎,這些合約使用了之前的區(qū)塊哈希作為隨機種子來挑選冠軍,區(qū)塊的選擇則取決于當前區(qū)塊的時間戳。通常來說,當節(jié)點確認一個區(qū)塊時,它會為這個區(qū)塊設(shè)置一個時間戳,這個時間一般是節(jié)點的本地系統(tǒng)時間。但是,節(jié)點可以在900s的范圍之內(nèi)隨意改變這個時間戳,與此同時其他節(jié)點仍然會接受并確認它。節(jié)點處理一個新的區(qū)塊時,如果新的區(qū)塊的時間戳大于上一個區(qū)塊,并且時間戳之差小于900秒,那么這個新區(qū)塊的時間戳就是合法的。因此有一些攻擊者就可以通過改變時間戳來控制合約的輸出結(jié)果 。
解決方案:
時間戳依賴的問題相對來說較難解決,只要在智能合約中使用了隨機數(shù),就很難保證節(jié)點在區(qū)塊驗證過程中不作弊,因為智能合約中的隨機數(shù)通常情況下只能根據(jù)節(jié)點的本地時間計算, 而本地時間又是可以被惡意偽造的,因此這種方法并不安全。通常的解決方案是使用鏈外的安全可信的第三方提供的服務(wù)來獲取隨機數(shù)。
3 智能合約安全管理
3.1 合約安全審計方法
智能合約的安全審計就是指將合約部署到區(qū)塊鏈上之前對合約代碼進行全面審查的過程,安全審計可以很大程度上減少合約代碼中存在漏洞和問題,避免合約部署后出現(xiàn)可能會出現(xiàn)的損失。
目前智能合約的安全審計分為人工審計和自動化審計,隨著智能合約的發(fā)展人工審計的方法已經(jīng)基本被自動化審計所取代,目前市面上有三種主流的自動化審計方法。
1、特征代碼匹配,智能合約的特征代碼匹配與傳統(tǒng)的特征代碼匹配類似,都是對常見的一些會導(dǎo)致問題出現(xiàn)的代碼進行提取、抽象,然后形成固定的匹配模塊對待檢測源碼進行檢測。這種檢測方法優(yōu)速度快、迅速響應(yīng)新漏洞,缺點則是使用范圍有限、漏報率高。
2、基于形式化驗證的自動化審計方法,這種方法采用 F-framework 和 K framework,將 EVM 轉(zhuǎn)化為一個 Formal? model。其中Formal 是航空航天領(lǐng)域常見的一種形式化驗證框架, K framework 則是一個語義的轉(zhuǎn)化框架。
3、基于符號執(zhí)行和符號抽象自動化審計。這也是目前最常用的方法,這種方法是指分析智能合約時,首先通過編譯源碼,可以形成 EVM OPCODE,然后輸入到自動化分析引擎轉(zhuǎn)化成 CFG,再利用這兩種方法進行分析。比較典型的是 Detente 和 Secured 系統(tǒng),這種方法可以降低誤報率和漏報率,但是也存在繁瑣和耗時的缺點。
自動化的審計方法可以很大程度上減少代碼問題造成的安全漏洞,但是目前現(xiàn)存的集中分析方法仍然存在流程繁瑣和耗時的問題。
3.2 合約安全監(jiān)測工具
目前市面上已經(jīng)有許多針對智能合約安全監(jiān)測方面的工具出現(xiàn),以下對較為常見的監(jiān)測工具做了簡要的介紹:
Mythril是一個針對以太坊智能合約的安全分析工具,Mythril可以檢測出包括整數(shù)溢出等一系列的常見安全問題,但Mythril針對合約內(nèi)的業(yè)務(wù)邏輯卻無能為力。
Oyente提供了一系列針對EVM漏洞檢測的啟發(fā)式引擎驅(qū)動,它不僅可以準確地找出代碼中的安全隱患,還能保證較低的誤報率。Oyente是一種符號執(zhí)行工具,可以直接運行在以太坊虛擬機(EVM)字節(jié)代碼上。
Manticore是一種符號化的執(zhí)行引擎, 包括EVM在內(nèi)的多種模式, 支持具體程序方案、符號化執(zhí)行驅(qū)動和斷言檢測等.
REMIX是一種基于瀏覽器的智能合約編寫和漏洞修補的IDE JavaScript應(yīng)用, 內(nèi)嵌的靜態(tài)分析工具可以針對已知的預(yù)定義漏洞進行檢測.
F*是一種用于程序驗證的通用函數(shù)式編程工具,支持驗證工具的自動執(zhí)行和基于依賴類型證明的表達, 可以對實際智能合約的語義正確性和運行過程的安全性進行驗證。但是, 現(xiàn)有的形式化驗證和程序分析工具多是針對已知漏洞的檢測和驗證.未來的研究將更加關(guān)注現(xiàn)有的智能合約的反模式, 構(gòu)造動態(tài)檢測的程序分析工具。
4 總結(jié)
本文對區(qū)塊鏈智能合約的安全性做了一定分析,針對合約代碼編寫過程中可能會出現(xiàn)的一些問題和漏洞,提出了一些改進建議。針對本文的建議和方案,已經(jīng)在供應(yīng)鏈金融、金融交易等項目中應(yīng)用,使用智能合約實現(xiàn)存證與查證、數(shù)據(jù)安全共享與交換、風險控制等執(zhí)行并寫入?yún)^(qū)塊鏈,為更多的區(qū)塊鏈項目中智能合約的安全使用提供參考。
參考文獻
[1]? Lou L, Ch D H, Frolicked H, ET AL. Making Smart Contracts Smarter[C]// A cm Issac Conference on Computer & Communications Security. 2016.
[2]? Mossback A, Miller A, Chi E, ET AL. Hawk: The Block chain Model of Cryptography
and Privacy-Preserving Smart Contracts[C]// Security & Privacy. 2016.
[3] 胡凱, 白曉敏, 高靈超,等. 智能合約的形式化驗證方法[J]. 信息安全研究, 2016, 2(12):1080-1089.
[4] 朱巖, 甘國華, 鄧迪, 姬菲菲, 陳愛平 -區(qū)塊鏈關(guān)鍵技術(shù)中的安全性研究[J].信息安全研究, 2016
[5] 賀海武,延安,陳澤華. 基于區(qū)塊鏈的智能合約技術(shù)與應(yīng)用綜述[J]. 計算機研究與發(fā)展, 2018, 55(11):2452-2466.
[6] 楊茜,黃曉芳. 一個基于盲簽名技術(shù)的智能合約模型[J]. 西南科技大學(xué)學(xué)報, 2018, v.33;No.130(02):99-103.
[7] 楊茜. 基于區(qū)塊鏈的智能合約研究與實現(xiàn)[D]. 西南科技大學(xué), 2018.
[8] 馬春光, 安婧, 畢偉, et al. 區(qū)塊鏈中的智能合約[J]. 信息網(wǎng)絡(luò)安全, 2018, 215(11):13-22.
[9] 畢曉冰, 馬兆豐, 徐明昆. 區(qū)塊鏈智能合約安全開發(fā)技術(shù)研究與實現(xiàn)[J]. 信息安全與通信保密, 2018(12):63-73.
[10] 孫煒. 淺談區(qū)塊鏈虛擬機[J]. 信息通信技術(shù)與政策, 2018, No.289(07):41-43.
[11] 馬昂, 潘曉, 吳雷, et al. 區(qū)塊鏈技術(shù)基礎(chǔ)及應(yīng)用研究綜述[J]. 信息安全研究, 2017, 3(11).
[12] 邢少敏, 馮維, 王泉景. 基于區(qū)塊鏈技術(shù)的涉密電子文檔保護方案研究[J]. 信息安全研究, 2017(10):22-30.
[13] 邵義勇. 兩種特殊性質(zhì)的代理簽名方案研究[D]. 華東師范大學(xué), 2008.
[14] 黃潔華. 眾籌區(qū)塊鏈上的智能合約設(shè)計[J]. 信息安全研究, 2017, 3(3):211-219.