首頁 web前端 js教程 Node.js 沙箱環境使用步驟詳解

Node.js 沙箱環境使用步驟詳解

May 21, 2018 pm 02:25 PM
javascript node.js 步驟

這次帶給大家Node.js 沙箱環境使用步驟詳解,Node.js 沙箱環境使用的注意事項有哪些,下面就是實戰案例,一起來看一下。

node官方文件裡提到node的vm模組可以用來做沙箱環境執行程式碼,對程式碼的上下文環境做隔離。

\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)
登入後複製
除了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)
登入後複製
如果我們把要執行的程式碼改成直接賦值的話就可以正常執行了,但也產生了全域污染(全域的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);     // vm
登入後複製
runInContext在傳入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)
登入後複製
可以透過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版本中

新增了vm.Module也可以做到延遲執行,vm.Module主要用來支援ES6 module,而且它的context在創建的時候就已經綁定好了,關於vm.Module目前還需要在命令列使用flag來啟用支援

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中文網其它相關文章!

推薦閱讀:

Vue專案webpack打包部署時Tomcat刷新封包404錯誤問題如何處#理

vue addRoutes實作動態權限路由選單步驟詳解

以上是Node.js 沙箱環境使用步驟詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何在iPhone中使Google地圖成為預設地圖 如何在iPhone中使Google地圖成為預設地圖 Apr 17, 2024 pm 07:34 PM

iPhone上的預設地圖是Apple專有的地理位置供應商「地圖」。儘管地圖越來越好,但它在美國以外的地區運作不佳。與谷歌地圖相比,它沒有什麼可提供的。在本文中,我們討論了使用Google地圖成為iPhone上的預設地圖的可行性步驟。如何在iPhone中使Google地圖成為預設地圖將Google地圖設定為手機上的預設地圖應用程式比您想像的要容易。請依照以下步驟操作–先決條件步驟–您必須在手機上安裝Gmail。步驟1–開啟AppStore。步驟2–搜尋“Gmail”。步驟3–點選Gmail應用程式旁

升級微信最新版本的步驟(輕鬆掌握微信最新版本的升級方法) 升級微信最新版本的步驟(輕鬆掌握微信最新版本的升級方法) Jun 01, 2024 pm 10:24 PM

不斷推出新版本以提供更好的使用體驗,微信作為中國的社交媒體平台之一。升級微信至最新版本是非常重要的,家人和同事的聯繫、為了保持與朋友、及時了解最新動態。 1.了解最新版本的特性與改進了解最新版本的特性與改進非常重要,在升級微信之前。效能改進和錯誤修復,透過查看微信官方網站或應用程式商店中的更新說明、你可以了解新版本所帶來的各種新功能。 2.檢查目前微信版本我們需要檢查目前手機上已安裝的微信版本、在升級微信之前。點擊,打開微信應用“我”然後選擇,菜單“關於”在這裡你可以看到當前微信的版本號,。 3.打開應

此 Apple ID 尚未在 iTunes Store 中使用:修復 此 Apple ID 尚未在 iTunes Store 中使用:修復 Jun 10, 2024 pm 05:42 PM

使用AppleID登入iTunesStore時,可能會在螢幕上拋出此錯誤提示「此AppleID尚未在iTunesStore中使用」。沒有什麼可擔心的錯誤提示,您可以按照這些解決方案集進行修復。修正1–更改送貨地址此提示出現在iTunesStore中的主要原因是您的AppleID個人資料中沒有正確的地址。步驟1–首先,開啟iPhone上的iPhone設定。步驟2–AppleID應位於所有其他設定的頂部。所以,打開它。步驟3–在那裡,打開“付款和運輸”選項。步驟4–使用面容ID驗證您的存取權限。步驟

Shazam應用程式在iPhone中無法運作:修復 Shazam應用程式在iPhone中無法運作:修復 Jun 08, 2024 pm 12:36 PM

iPhone上的Shazam應用程式有問題? Shazam可協助您透過聆聽歌曲找到歌曲。但是,如果Shazam無法正常工作或無法識別歌曲,則必須手動對其進行故障排除。修復Shazam應用程式不會花費很長時間。因此,無需再浪費時間,請按照以下步驟解決Shazam應用程式的問題。修正1–禁用粗體文字功能iPhone上的粗體文字可能是Shazam無法正常運作的原因。步驟1–您只能從iPhone設定執行此操作。所以,打開它。步驟2–接下來,開啟其中的「顯示和亮度」設定。步驟3–如果您發現啟用了“粗體文本

Win11系統管理員權限取得步驟詳解 Win11系統管理員權限取得步驟詳解 Mar 08, 2024 pm 09:09 PM

Windows11作為微軟最新推出的作業系統,深受廣大用戶喜愛。在使用Windows11的過程中,有時候我們需要取得系統管理員權限,以便進行一些需要權限的操作。接下來將詳細介紹在Windows11中取得系統管理員權限的步驟。第一步,點擊“開始功能表”,在左下角可以看到Windows圖標,點擊該圖標即可開啟“開始功能表”。第二步,在「開始功能表」中尋找並點擊「

iPhone中缺少時鐘應用程式:如何修復 iPhone中缺少時鐘應用程式:如何修復 May 03, 2024 pm 09:19 PM

您的手機中缺少時鐘應用程式嗎?日期和時間仍將顯示在iPhone的狀態列上。但是,如果沒有時鐘應用程序,您將無法使用世界時鐘、碼錶、鬧鐘等多項功能。因此,修復時鐘應用程式的缺失應該是您的待辦事項清單的首位。這些解決方案可以幫助您解決此問題。修復1–放置時鐘應用程式如果您錯誤地從主畫面中刪除了時鐘應用程序,您可以將時鐘應用程式放回原位。步驟1–解鎖iPhone並開始向左側滑動,直到到達「應用程式庫」頁面。步驟2–接下來,在搜尋框中搜尋「時鐘」。步驟3–當您在搜尋結果中看到下方的「時鐘」時,請按住它並

iPhone螢幕截圖不起作用:如何修復 iPhone螢幕截圖不起作用:如何修復 May 03, 2024 pm 09:16 PM

螢幕截圖功能在您的iPhone上不起作用嗎?截圖非常簡單,因為您只需同時按住「提高音量」按鈕和「電源」按鈕即可抓取手機螢幕。但是,還有其他方法可以在設備上捕獲幀。修復1–使用輔助觸控使用輔助觸控功能截取螢幕截圖。步驟1–轉到您的手機設定。步驟2–接下來,點選以開啟「輔助功能」設定。步驟3–開啟「觸摸」設定。步驟4–接下來,開啟「輔助觸控」設定。步驟5–打開手機上的「輔助觸控」。步驟6–打開“自訂頂級選單”以存取它。步驟7–現在,您只需將這些功能中的任何一個連結到螢幕擷取即可。因此,點擊那裡的首

iPhone上的蜂窩數據網路速度慢:修復 iPhone上的蜂窩數據網路速度慢:修復 May 03, 2024 pm 09:01 PM

在iPhone上面臨滯後,緩慢的行動數據連線?通常,手機上蜂窩互聯網的強度取決於幾個因素,例如區域、蜂窩網絡類型、漫遊類型等。您可以採取一些措施來獲得更快、更可靠的蜂窩網路連線。修復1–強制重啟iPhone有時,強制重啟設備只會重置許多內容,包括蜂窩網路連線。步驟1–只需按一次音量調高鍵並放開即可。接下來,按降低音量鍵並再次釋放它。步驟2–過程的下一部分是按住右側的按鈕。讓iPhone完成重啟。啟用蜂窩數據並檢查網路速度。再次檢查修復2–更改資料模式雖然5G提供了更好的網路速度,但在訊號較弱

See all articles