摘要:而標(biāo)準(zhǔn)庫(kù)中的是不安全的,用戶腳本可以輕易突破沙箱環(huán)境,獲取主程序的上述代碼在執(zhí)行時(shí),程序在第二行就直接退出,虛擬機(jī)環(huán)境中的代碼逃逸,獲得了主線程的變量,并調(diào)用,造成主程序非正常退出。
NPM酷庫(kù),每天兩分鐘,了解一個(gè)流行NPM庫(kù)。
今天我們要了解的庫(kù)是 vm2,則是一個(gè)Node.js 官方 vm 庫(kù)的替代品,主要解決了安全問(wèn)題。
不安全的vm在Node.js官方標(biāo)準(zhǔn)庫(kù)中有一個(gè)vm庫(kù),用來(lái)在V8虛擬機(jī)環(huán)境中編譯執(zhí)行JS代碼。通常,我們用vm庫(kù)來(lái)實(shí)現(xiàn)一個(gè)沙箱,在代碼主程序之外執(zhí)行額外的JS腳本。
有時(shí),我們需要vm虛擬機(jī)來(lái)執(zhí)行不受信任的代碼,這些代碼可能是由用戶提交的,比如在脈沖云接口文檔管理中,允許用戶提交Mock.js腳本生成模擬接口數(shù)據(jù)。而Node.js標(biāo)準(zhǔn)庫(kù)中的vm是不安全的,用戶腳本可以輕易突破沙箱環(huán)境,獲取主程序的Context!
const vm = require("vm"); vm.runInNewContext("this.constructor.constructor("return process")().exit()"); console.log("Never gets executed.");
上述代碼在執(zhí)行時(shí),程序在第二行就直接退出,vm虛擬機(jī)環(huán)境中的代碼逃逸,獲得了主線程的 process 變量,并調(diào)用 process.exit(),造成主程序非正常退出。
vm不安全的原因上文中的代碼使用了runInNewContext函數(shù)簡(jiǎn)寫(xiě),等價(jià)于如下代碼:
const vm = require("vm"); const sandbox = {}; const script = new vm.Script("this.constructor.constructor("return process")().exit()"); const context = vm.createContext(sandbox); script.runInContext(context); console.log("Never gets executed.");
從代碼中得知,創(chuàng)建vm環(huán)境時(shí),首先要初始化一個(gè)對(duì)象 sendbox,這個(gè)對(duì)象就是vm中腳本執(zhí)行時(shí)的全局環(huán)境Context,vm 腳本中全局 this 指向的就是這個(gè)對(duì)象。
而vm中腳本等同于:
const sandbox = this; // 獲取Context const ObjectConstructor = this.constructor; // 獲取 Object 對(duì)象構(gòu)造函數(shù) const FunctionConstructor = ObjectConstructor.constructor; // 獲取 Function 對(duì)象構(gòu)造函數(shù) const myfun = FunctionConstructor("return process"); // 構(gòu)造一個(gè)函數(shù),返回process全局變量 const process = myfun(); process.exit();
從上邊腳本中可以看出vm不安全的原因。vm內(nèi)部腳本的Context對(duì)象是在主程序中定義的,根據(jù)JS原型鏈原理,可以輕松獲取主程序中的 Function 對(duì)象,用主程序的 Function 對(duì)象構(gòu)造一個(gè)函數(shù),那么這個(gè)函數(shù)運(yùn)行時(shí),就是在主程序閉包環(huán)境中執(zhí)行的!所以,我們輕易地獲取到了主程序的全局對(duì)象 process,最終控制主程序!
安全的vm2vm2就是專(zhuān)門(mén)為了解決vm的安全問(wèn)題而誕生的。
const { VM } = require("vm2"); const vm = new VM({ timeout: 1000, sandbox: {} }); vm.run(`process.exit()`); // TypeError: process.exit is not a functionvm2 特性:
運(yùn)行不受信任的JS腳本
沙箱的終端輸出信息完全可控
沙箱內(nèi)可以受限地加載modules
可以安全地向沙箱間傳遞callback
死循環(huán)攻擊免疫 while (true) {}
vm2 原理:首先,vm2基于vm,使用官方的vm庫(kù)構(gòu)建沙箱環(huán)境。然后使用JavaScript的Proxy技術(shù)來(lái)防止沙箱腳本逃逸。
參考資料VM2 https://github.com/patriksime...
Proxy https://developer.mozilla.org...
歡迎關(guān)注公眾號(hào):梁興臣每天了解一個(gè)NPM庫(kù),一年后成為Node.js高手
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/90602.html
摘要:當(dāng)運(yùn)行函數(shù)的時(shí)候,只能訪問(wèn)自己的本地變量和全局變量,不能訪問(wèn)構(gòu)造器被調(diào)用生成的上下文的作用域。如何建立一個(gè)更安全一些的沙箱通過(guò)上文的探究,我們并沒(méi)有找到一個(gè)完美的方案在建立安全的隔離的沙箱。 showImg(https://segmentfault.com/img/remote/1460000014575992); 有哪些動(dòng)態(tài)執(zhí)行腳本的場(chǎng)景? 在一些應(yīng)用中,我們希望給用戶提供插入自定義...
摘要:酷庫(kù),每天兩分鐘,了解一個(gè)流行庫(kù)。今天我們要了解的就是一個(gè)可以使得從文件中加載環(huán)境變量的庫(kù),使用,我們只需要將程序的環(huán)境變量配置寫(xiě)在文件中。 NPM酷庫(kù),每天兩分鐘,了解一個(gè)流行NPM庫(kù)?!?我們經(jīng)常需要Node.js程序運(yùn)行時(shí)加載不同的配置,比如開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境的數(shù)據(jù)數(shù)據(jù)庫(kù)配置就可能不一樣,使用 process.env.DB_HOST 環(huán)境變量,可以在Node.js程序內(nèi)部方便獲取...
摘要:今天我們要了解的庫(kù)是,一個(gè)專(zhuān)門(mén)用來(lái)控制輸出調(diào)試日志的庫(kù)。但是,隨著項(xiàng)目規(guī)模增加,控制臺(tái)輸出的日志就會(huì)堆積很多而不可讀。庫(kù)就是一款專(zhuān)門(mén)控制日志輸出的庫(kù),能夠完美解決我們的上述需求。 NPM酷庫(kù),每天兩分鐘,了解一個(gè)流行NPM庫(kù)。 今天我們要了解的庫(kù)是debug,一個(gè)專(zhuān)門(mén)用來(lái)控制輸出調(diào)試日志的庫(kù)。 通常,我們直接使用 console.log 輸出調(diào)試日志,使用console對(duì)象直接將日志輸...
摘要:酷庫(kù),每天兩分鐘,了解一個(gè)流行庫(kù)。昨天認(rèn)識(shí)了一個(gè)在環(huán)境下操作的庫(kù),實(shí)現(xiàn)了接口,用起來(lái)十分方便。今天,我們要學(xué)習(xí)的就是一個(gè)純實(shí)現(xiàn)的,可以在環(huán)境中模擬出環(huán)境,像這樣對(duì)依賴(lài)的庫(kù)就可以在中運(yùn)行了。 NPM酷庫(kù),每天兩分鐘,了解一個(gè)流行NPM庫(kù)。 昨天認(rèn)識(shí)了一個(gè)在Node.js環(huán)境下操作HTML的庫(kù) cheerio,cheerio實(shí)現(xiàn)了jQuery接口,用起來(lái)十分方便。為什么不直接用jQuery...
摘要:酷庫(kù),每天兩分鐘,了解一個(gè)流行庫(kù)。昨天認(rèn)識(shí)了一個(gè)在環(huán)境下操作的庫(kù),實(shí)現(xiàn)了接口,用起來(lái)十分方便。今天,我們要學(xué)習(xí)的就是一個(gè)純實(shí)現(xiàn)的,可以在環(huán)境中模擬出環(huán)境,像這樣對(duì)依賴(lài)的庫(kù)就可以在中運(yùn)行了。 NPM酷庫(kù),每天兩分鐘,了解一個(gè)流行NPM庫(kù)。 昨天認(rèn)識(shí)了一個(gè)在Node.js環(huán)境下操作HTML的庫(kù) cheerio,cheerio實(shí)現(xiàn)了jQuery接口,用起來(lái)十分方便。為什么不直接用jQuery...
閱讀 2913·2021-11-18 10:02
閱讀 2381·2021-09-30 09:47
閱讀 1975·2021-09-27 14:01
閱讀 3242·2021-08-16 11:00
閱讀 3252·2019-08-30 11:06
閱讀 2476·2019-08-29 17:29
閱讀 1634·2019-08-29 13:19
閱讀 518·2019-08-26 13:54