這次帶給大家怎麼使用Node.js沙箱環境,使用Node.js沙箱環境的注意事項有哪些,下面就是實戰案例,一起來看一下。
#先看一個例子\A common use case is to run the code in a sandboxed environment. The sandboxed code uses a different V8 Context, meaning that it has a different global object than the Context, meaning that it has a different global object than the rest of the .
const vm = require('vm'); let a = 1; var result = vm.runInNewContext('var b = 2; a = 3; a + b;', {a}); console.log(result); // 5 console.log(a); // 1 console.log(typeof b); // undefined沙箱環境中執行的程式碼對外部程式碼沒有產生任何影響,無論是新宣告的變數b,或是重新賦值的變數a。注意最後一行的程式碼預設會被加上return關鍵字,因此無需手動添加,一旦添加的話不會靜默忽略,而是執行報錯。
const vm = require('vm'); let a = 1; var result = vm.runInNewContext('var b = 2; a = 3; return a + b;', {a}); console.log(result); console.log(a); console.log(typeof b);如下所示
evalmachine.<anonymous>:1 var b = 2; a = 3; return a + b; ^^^^^^ SyntaxError: Illegal return statement at new Script (vm.js:74:7) at createScript (vm.js:246:10) at Object.runInNewContext (vm.js:291:10) at Object.<anonymous> (/Users/xiji/workspace/learn/script.js:3:17) at Module._compile (internal/modules/cjs/loader.js:678:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10) at Module.load (internal/modules/cjs/loader.js:589:32) at tryModuleLoad (internal/modules/cjs/loader.js:528:12) at Function.Module._load (internal/modules/cjs/loader.js:520:3) at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)</anonymous></anonymous>除了runInNewContext外,vm還提供了runInThisContext和runInContext兩個方法都可以用來執行程式碼runInThisContext無法指定context
const vm = require('vm'); let localVar = 'initial value'; const vmResult = vm.runInThisContext('localVar += "vm";'); console.log('vmResult:', vmResult); console.log('localVar:', localVar); console.log(global.localVar);由於無法存取本地的作用域,只能存取到目前的global對象,因此上面的程式碼會因為找不到localVal而報錯
evalmachine.<anonymous>:1 localVar += "vm"; ^ ReferenceError: localVar is not defined at evalmachine.<anonymous>:1:1 at Script.runInThisContext (vm.js:91:20) at Object.runInThisContext (vm.js:298:38) at Object.<anonymous> (/Users/xiji/workspace/learn/script.js:3:21) at Module._compile (internal/modules/cjs/loader.js:678:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10) at Module.load (internal/modules/cjs/loader.js:589:32) at tryModuleLoad (internal/modules/cjs/loader.js:528:12) at Function.Module._load (internal/modules/cjs/loader.js:520:3) at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)</anonymous></anonymous></anonymous>如果我們把要執行的程式碼改成直接賦值的話就可以正常執行了,但也產生了全域污染(全域的localVar變數)
const vm = require('vm'); let localVar = 'initial value'; const vmResult = vm.runInThisContext('localVar = "vm";'); console.log('vmResult:', vmResult); // vm console.log('localVar:', localVar); // initial value console.log(global.localVar); // vmrunInContext在傳入context參數上與runInNewContext有所區別runInContext傳入的context物件不為空而且必須是經vm.createContext( )處理過的,否則會報錯。 runInNewContext的context參數是非必須的,且無需經過vm.createContext處理。 runInNewContext和runInContext因為有指定context,所以不會向runInThisContext那樣產生全域污染(不會產生全域的localVar變數)
const vm = require('vm'); let localVar = 'initial value'; const vmResult = vm.runInNewContext('localVar = "vm";'); console.log('vmResult:', vmResult); // vm console.log('localVar:', localVar); // initial value console.log(global.localVar); // undefined當需要一個沙箱環境執行多個腳本片段的時候,可以透過多次呼叫runInContext方法但是傳入同一個vm.createContext()回傳值實作。
逾時控制及錯誤擷取
vm針對要執行的程式碼提供了逾時機制,透過指定timeout參數即可以runInThisContext為例const vm = require('vm'); let localVar = 'initial value'; const vmResult = vm.runInThisContext('while(true) { 1 }; localVar = "vm";', { timeout: 1000});
vm.js:91 return super.runInThisContext(...args); ^ Error: Script execution timed out. at Script.runInThisContext (vm.js:91:20) at Object.runInThisContext (vm.js:298:38) at Object.<anonymous> (/Users/xiji/workspace/learn/script.js:3:21) at Module._compile (internal/modules/cjs/loader.js:678:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10) at Module.load (internal/modules/cjs/loader.js:589:32) at tryModuleLoad (internal/modules/cjs/loader.js:528:12) at Function.Module._load (internal/modules/cjs/loader.js:520:3) at Function.Module.runMain (internal/modules/cjs/loader.js:719:10) at startup (internal/bootstrap/node.js:228:19)</anonymous>可以透過try catch來捕獲程式碼錯誤
const vm = require('vm'); let localVar = 'initial value'; try { const vmResult = vm.runInThisContext('while(true) { 1 }; localVar = "vm";', { timeout: 1000 }); } catch(e) { console.error('executed code timeout'); }
#延遲執行
#vm除了即時執行程式碼之外,也可以先編譯然後過一段時間再執行,這就需要提到vm.Script了。其實無論是runInNewContext、runInThisContext還是runInThisContext,背後其實都創建了Script,從之前的報錯信息就可以看出來接下來我們就用vm.Script來重寫本文開頭的例子const vm = require('vm'); let a = 1; var script = new vm.Script('var b = 2; a = 3; a + b;'); setTimeout(() => { let result = script.runInNewContext({a}); console.log(result); // 5 console.log(a); // 1 console.log(typeof b); // undefined }, 300);除了vm. Script,node在9.6版本中
node --experimental-vm-module index.js
#vm作為沙箱環境安全性嗎?
vm相對於eval來說更安全一些,因為它隔離了當前的上下文環境了,但儘管如此依然可以存取標準的JS API和全域的NodeJS環境,因此vm並不安全,這個在官方文檔裡就提到了The vm module is not a security mechanism. Do not use it to run untrusted code請看下面的例子
const vm = require('vm'); vm.runInNewContext("this.constructor.constructor('return process')().exit()") console.log("The app goes on...") // 永远不会输出為了避免上面這種情況,可以將上下文簡化成只包含基本類型,如下所示
let ctx = Object.create(null); ctx.a = 1; // ctx上不能包含引用类型的属性 vm.runInNewContext("this.constructor.constructor('return process')().exit()", ctx);針對原生vm存在的這個問題,有人開發了vm2包,可以避免上述問題,但是也不能說vm2就一定是安全的
const {VM} = require('vm2'); new VM().run('this.constructor.constructor("return process")().exit()');雖然執行上述程式碼沒有問題,但是由於vm2的timeout對於非同步程式碼不起作用,所以下面的程式碼永遠不會執行結束。
const { VM } = require('vm2'); const vm = new VM({ timeout: 1000, sandbox: {}}); vm.run('new Promise(()=>{})');即使希望透過重新定義Promise的方式來停用Promise的話,還是一個可以繞過的
const { VM } = require('vm2'); const vm = new VM({ timeout: 1000, sandbox: { Promise: function(){}} }); vm.run('Promise = (async function(){})().constructor;new Promise(()=>{});');相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章! 推薦閱讀: #
以上是怎麼使用Node.js沙箱環境的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

禪工作室 13.0.1
強大的PHP整合開發環境

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具