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