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