摘要:背景前一陣子比特股的創(chuàng)始人質(zhì)疑了系統(tǒng)中的一系列問題,絕大多數(shù)都被的創(chuàng)始人之一正面回應(yīng)過了,具體可以看看這個(gè)但是有一個(gè)問題沒有回應(yīng)或者說還沒有提出解決方案。的組合堪稱完美。
背景
前一陣子比特股的創(chuàng)始人Daniel Larimer質(zhì)疑了lisk系統(tǒng)中的一系列問題,絕大多數(shù)都被lisk的創(chuàng)始人之一Max正面回應(yīng)過了,具體可以看看這個(gè)http://ethereum.stackexchange...
但是有一個(gè)問題Max沒有回應(yīng)或者說還沒有提出解決方案。
那就是lisk側(cè)鏈的運(yùn)行環(huán)境,Larimer說
“Lisk所面臨的大多數(shù)問題,都可以通過一個(gè)高度定制的JavaScript 環(huán)境來解決。”
否則,lisk的系統(tǒng)面臨兩大考驗(yàn):
首先,也是最重要的,lisk目前的沙箱機(jī)制不足以限制側(cè)鏈代碼的權(quán)限,也就是說無法運(yùn)行不受信任的代碼,那些代碼可能會盜取服務(wù)器的關(guān)鍵信息,或者直接對服務(wù)器進(jìn)行破壞
其次,是關(guān)于側(cè)鏈開發(fā)者的,lisk的側(cè)鏈代碼是運(yùn)行在一個(gè)擁有全部能力的javascript環(huán)境,這里面有些可以導(dǎo)致不確定因素的函數(shù),比如Math.random,lisk官方的開發(fā)文檔特別指出希望開發(fā)者避開這些函數(shù),這對開發(fā)者會造成心智負(fù)擔(dān),如果是一個(gè)定制版的javascript環(huán)境呢,直接把那些導(dǎo)致不確定因素的函數(shù)干掉,開發(fā)者根本不需要花費(fèi)額外的精力去避開那些陷阱。
我們先說說為什么要用沙箱。沙箱(sandbox)是云計(jì)算平臺廣泛采用的安全防范措施,是一種訪問控制機(jī)制,其目的是為了限制應(yīng)用代碼的權(quán)限,防止應(yīng)用代碼對系統(tǒng)進(jìn)行隨意的訪問和破壞,因?yàn)樵谠朴?jì)算平臺中,應(yīng)用代碼是由各種各樣的第三方開發(fā)者實(shí)現(xiàn)的,他們的代碼是不能被信任的,需要沙箱來做一層隔離,讓這些應(yīng)用代碼只能做有限的事情。
lisk在區(qū)塊鏈領(lǐng)域是很類似于云計(jì)算平臺的,他們提供一些服務(wù),允許第三方開發(fā)者基于這些服務(wù)構(gòu)建他們自己的應(yīng)用程序(即dapps)。
所以lisk也需要沙箱機(jī)制來保證dapps的作者無法作惡,lisk的做法是提供一個(gè)定制版的nodejs環(huán)境來達(dá)到這一目的。
具體實(shí)現(xiàn)在這段代碼里,https://github.com/LiskHQ/lis...
我經(jīng)過分析,發(fā)現(xiàn)這個(gè)sandbox名不副實(shí),只是使用管道手段實(shí)現(xiàn)了進(jìn)程間通訊,而且是使用一種繞彎的方式實(shí)現(xiàn)的。nodejs的進(jìn)程間通訊可以通過javascript代碼直接實(shí)現(xiàn),為什么要用c++來實(shí)現(xiàn)呢?
我?guī)е@個(gè)疑問,和一些期望,親手做了一個(gè)實(shí)驗(yàn)。
我首先使用lisk-cli創(chuàng)建一個(gè)hello world側(cè)鏈
lisk-cli dapp -a
接著我在側(cè)鏈程序的入口處 加了一段代碼
console.log(require("fs").readFileSync("../../config.json"))
然后運(yùn)行之,于是我得到了這個(gè)服務(wù)器主節(jié)點(diǎn)的受托人的所有密碼
"forging": { "secret": [ "wKyoJM1vS4ucHmWvxDSdcpC23mJwqfg3G6MKZoXaFfcnWHTqo7", "2aTWYPpQidVunxTg3y8YESYps7za6f9d4wYn9Gy2GuGnE7JX7V", "65uZNjL36Bdg2tkJnueYkd2n6YPe76fpdeYtgu7fso1m385mwD", …………
果然,這個(gè)沙箱并沒有起隔離的作用,擁有管理員的權(quán)限,這等于給黑客敞開了大門。
有人說,lisk系統(tǒng)設(shè)置了二級密碼,你獲取了他的一級密碼,還是沒法盜取他們的錢。
也有人說,可以通過Linux自身的權(quán)限機(jī)制,給側(cè)鏈代碼一個(gè)低級用戶,使之無法訪問其他用戶的文件。
這些都是治標(biāo)不治本的辦法,根本解決途徑是按照lisk預(yù)先設(shè)想的那樣,要讓沙箱名副其實(shí),做到真正的環(huán)境隔離,要讓側(cè)鏈代碼對外界一無所知。
解決方案
那么,如何實(shí)現(xiàn)真正的沙箱呢?有很多種方案,比如跳過nodejs,直接使用v8引擎,或者使用進(jìn)程級別的權(quán)限控制,比如windows系統(tǒng)的SetWindowsHookEx,當(dāng)然,lisk目前并不打算支持windows版本的完整版錢包,那么在linux系統(tǒng)中可以使用seccomp技術(shù)。
我這里有種更簡單的方法,那就是利用nodejs自帶的vm模塊。
第一步 創(chuàng)建原生的javascript虛擬機(jī)
var vm = require("vm"); var context = vm.createContext(); vm.runInContext(sideChainCode, context);
這幾行代碼完成了對側(cè)鏈代碼的隔離,sideChainCode中只能進(jìn)行純粹的運(yùn)算邏輯,只能使用少量的v8引擎內(nèi)置的javascript標(biāo)準(zhǔn)庫。甚至連setTimeout,console.log都沒有。
我們需要做些額外的工作。
比如,給運(yùn)行環(huán)境添加setTimeout和clearTimeout
context.setTimeout= function(fn, delay) { if (typeof(fn) == "string") { setTimeout(new Function(fn), delay) } else { setTimeout(fn, delay) } }; context.clearTimeout = clearTimeout;
添加日志打印功能,讓側(cè)鏈的日志,轉(zhuǎn)發(fā)到主系統(tǒng)的中
global.print = send.bind(global, "stdout"); global.console = { log: send.bind(global, "stdout") }; global.process = { stdout: { write: send.bind(global, "stdout") } }; global.postMessage = send.bind(global, "message");
另外,還可以禁用那些導(dǎo)致不確定因素的函數(shù)
global.Math.random = undefined;
這些都做完以后,側(cè)鏈代碼的訪問權(quán)限就被限制在一個(gè)狹小的范圍內(nèi)了。它們無法使用require,fs,http等nodejs內(nèi)置的標(biāo)準(zhǔn)庫。
這樣安全的目的達(dá)到了,但是引發(fā)另一個(gè)問題,那就是功能性的問題了,不能使用那些額外的庫,只有js的標(biāo)準(zhǔn)庫也太不方便了,很多復(fù)雜功能無法實(shí)現(xiàn),特別是沒有了require之后,連模塊化都做不到了。
所以我們需要第二步。
第二步 webpack
webpack本來是一個(gè)前端常用的打包方案,用于模塊化的管理前端項(xiàng)目。很多人忽略了其實(shí)在后端webpack同樣適用,并且可以把node_modules里的庫,甚至nodejs的一部分內(nèi)置庫一起打包。
也就是說前端能用的js庫,除了UI相關(guān)的之外,在側(cè)鏈沙箱內(nèi),也都可以用,比如async,bytebuffer,crypto,js-nacl,bignum等等,這對于側(cè)鏈來說夠用了。
那些不能用的庫,比如文件系統(tǒng)、多進(jìn)程、網(wǎng)絡(luò)模塊,正是我們想要拋棄的。
vm + webpack的組合堪稱完美。
這是日新月異的前端技術(shù)帶給javascript這門語言的福利,也是以太坊的solidity等新語言望塵莫及的。
不過我們還需要一些收尾的工作
第三步 掃清障礙
目前側(cè)鏈代碼中有些地方使用了一些比較復(fù)雜的庫,比如ed2curve,涉及到非常多的依賴,我們認(rèn)為是沒有必要的,這部分功能可以在主鏈中提供,通過進(jìn)程間通訊以api的方式提供給側(cè)鏈?zhǔn)褂谩?br>這樣也可以減輕側(cè)鏈代碼的累贅,還可以讓側(cè)鏈開發(fā)者更加輕松。這些代碼對整個(gè)框架的影響非常小,可以忽略不計(jì),但是它們依賴的庫卻占用了一半以上的代碼量,其中還包括了沙箱環(huán)境不允許的一些操作。
經(jīng)過分析,我發(fā)現(xiàn)只需要禁用modules/api/crypto.js中的兩個(gè)函數(shù)即可
Crypto.prototype.encrypt Crypto.prototype.decrypt
另外,js-nacl這個(gè)庫里依賴了fs模塊,但是相關(guān)函數(shù)并沒有被用到,暫時(shí)通過手工修改的方式,把fs相關(guān)代碼去掉就可以正常打包并運(yùn)行了。
最后,我把一個(gè)完整的側(cè)鏈項(xiàng)目和主鏈框架中的關(guān)鍵代碼打包放在這里了。http://o7dyh3w0x.bkt.clouddn....
關(guān)于側(cè)鏈和區(qū)塊鏈開發(fā)的問題,歡迎加群:485979564,一起討論交流
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91324.html
摘要:事實(shí)上,已經(jīng)成功了一半目前在區(qū)塊鏈領(lǐng)域融資金額排行第二,僅次于以太坊。以上這些,就是我們經(jīng)過深思熟慮后,雖有以太坊等珠玉在前,但我們依然要做一個(gè)同類型的產(chǎn)品的原因。 0 前言 首先要聲明一點(diǎn),我們和我們的一些朋友都是lisk的投資人和支持者,我們也相信lisk會成功。 事實(shí)上,lisk已經(jīng)成功了一半,目前在區(qū)塊鏈領(lǐng)域融資金額排行第二,僅次于以太坊。 那為什么我們還要做一個(gè)類似的Asch...
摘要:事實(shí)上,已經(jīng)成功了一半目前在區(qū)塊鏈領(lǐng)域融資金額排行第二,僅次于以太坊。以上這些,就是我們經(jīng)過深思熟慮后,雖有以太坊等珠玉在前,但我們依然要做一個(gè)同類型的產(chǎn)品的原因。 0 前言 首先要聲明一點(diǎn),我們和我們的一些朋友都是lisk的投資人和支持者,我們也相信lisk會成功。 事實(shí)上,lisk已經(jīng)成功了一半,目前在區(qū)塊鏈領(lǐng)域融資金額排行第二,僅次于以太坊。 那為什么我們還要做一個(gè)類似的Asch...
摘要:本文今天就淺嘗輒止的做個(gè)和的安全性對比首頁登陸。而則不必要求服務(wù)端是可信任的,他傳輸?shù)闹皇枪€,是安全可靠的。本系列文章只是進(jìn)行技術(shù)交流,不可用做其它用途,且須經(jīng)本人同意,方可轉(zhuǎn)載。 在幣圈,聽到對數(shù)字貨幣的質(zhì)疑之聲從來沒少過。為什么有人會質(zhì)疑呢?他們列出了很多理由(以下四點(diǎn)內(nèi)容摘自網(wǎng)絡(luò)): 數(shù)字貨幣是依附于網(wǎng)絡(luò)的,而中國并沒有獨(dú)立自主的網(wǎng)絡(luò)技術(shù),容易被敵對勢力利用數(shù)字貨幣損害中國利益...
摘要:本文今天就淺嘗輒止的做個(gè)和的安全性對比首頁登陸。而則不必要求服務(wù)端是可信任的,他傳輸?shù)闹皇枪€,是安全可靠的。本系列文章只是進(jìn)行技術(shù)交流,不可用做其它用途,且須經(jīng)本人同意,方可轉(zhuǎn)載。 在幣圈,聽到對數(shù)字貨幣的質(zhì)疑之聲從來沒少過。為什么有人會質(zhì)疑呢?他們列出了很多理由(以下四點(diǎn)內(nèi)容摘自網(wǎng)絡(luò)): 數(shù)字貨幣是依附于網(wǎng)絡(luò)的,而中國并沒有獨(dú)立自主的網(wǎng)絡(luò)技術(shù),容易被敵對勢力利用數(shù)字貨幣損害中國利益...
閱讀 2633·2021-11-19 09:56
閱讀 885·2021-09-24 10:25
閱讀 1653·2021-09-09 09:34
閱讀 2211·2021-09-09 09:33
閱讀 1066·2019-08-30 15:54
閱讀 552·2019-08-29 18:33
閱讀 1278·2019-08-29 17:19
閱讀 515·2019-08-29 14:19