ホームページ >ウェブフロントエンド >jsチュートリアル >Node.jsサンドボックス環境の使用方法
今回は、Node.jsサンドボックス環境の使い方と、Node.jsサンドボックス環境を使用する際の注意事項を紹介します。実際の事例を見てみましょう。
サンドボックス環境で実行されるコードは、新しく宣言された変数 b であっても、再割り当てされた変数 a であっても、外部コードには影響を与えません。 コードの最後の行はデフォルトで return キーワードを使用して追加されるため、手動で追加する必要はありません。追加すると無視されることはありませんが、エラーが報告されます。一般的な使用例は、サンドボックス環境でコードを実行することです。サンドボックス コードは、コードの残りの部分とは異なるグローバル オブジェクトを持つことを意味します。まず例を見てみましょう。
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
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 という 2 つのメソッドも用意されており、どちらもコードの実行に使用できます。 runInThisContext ではコンテキストを指定できません
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);ローカル スコープにはアクセスできないため、現在のものはグローバルオブジェクトにアクセスできるため、上記のコードは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)実行するコードを直接代入に変更すると正常に実行されますが、グローバル汚染も引き起こします( global 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 には指定されたコンテキストがあるため、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は、タイムアウトパラメータを指定することで、例としてInThisContextを実行できますtry catch
const vm = require('vm'); let localVar = 'initial value'; const vmResult = vm.runInThisContext('while(true) { 1 }; localVar = "vm";', { timeout: 1000});を通じてコードエラーをキャッチできます。
Delay
vm を実行するには、コードをすぐに実行するだけでなく、最初にコードをコンパイルして、しばらくしてから実行することもできます。これには、vm.Script を指定する必要があります。実際、runInNewContext、runInThisContext、または runInThisContext のいずれであっても、実際にはその背後で Script が作成されていることがわかります。次に、vm.Script を使用してこの記事の冒頭の例を書き直します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)
。バージョン 9.6 では、vm.Script に加えて、vm.Module が
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 は現在のコンテキストを分離するため eval より安全ですが、それでも標準の JS API とグローバル NodeJS 環境にアクセスできるため、vm は安全ではありません。これは公式ドキュメントに記載されています。 vm モジュールはセキュリティ機構ではありません。信頼できないコードの実行には使用しないでください以下の例を参照してください
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);上記の状況を回避するには、以下に示すようにコンテキストを単純化して基本タイプのみを含めることができます
node --experimental-vm-module index.jsネイティブvmのこの問題を考慮して、上記の問題を回避できるvm2パッケージを開発された方がいらっしゃいますが、必ずしもvm2が安全とは言えません
Promise を再定義して Promise を無効にしたい場合でも、バイパスすることができますconst vm = require('vm'); vm.runInNewContext("this.constructor.constructor('return process')().exit()") console.log("The app goes on...") // 永远不会输出上記コードの実行には問題ありませんが、 to vm2 タイムアウトは非同期コードには影響しないため、以下のコードは実行を終了しません。
let ctx = Object.create(null); ctx.a = 1; // ctx上不能包含引用类型的属性 vm.runInNewContext("this.constructor.constructor('return process')().exit()", ctx);
const {VM} = require('vm2'); new VM().run('this.constructor.constructor("return process")().exit()');この記事の事例を読んだ後は、方法を習得したと思います。さらに興味深い情報については、他の関連記事に注目してください。 PHP中国語ウェブサイトです! 推奨書籍:
WeChat ミニプログラムエントリーチュートリアル + ケースの詳細な分析
以上がNode.jsサンドボックス環境の使用方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。