λ€μ μ½λλ μκ° μ΄κ³Όλμ§ μμ΅λλ€.
const {VM} = require('vm2');
new VM({timeout:1}).run(`
function main(){
while(1){}
}
new Proxy({}, {
getPrototypeOf(t){
global.main();
}
})`);
μ΄μ λν μ’μ ν΄κ²°μ± μ μμ κ²μ λλ€. NodeJSλ λ¨μΌ νλ‘μΈμ€μ λλ€. while (1) {} 보νΈμλ κ²μ¬κΈ°κ° while (1) {}μ μν΄ μ°¨λ¨λμ§ μλλ‘ λ€μ€ νλ‘μΈμ€κ° νμν©λλ€. μ€νμ΄λλ Έλ νλ‘μ νΈμ λ€μ λΆμ λΆμΌ μ μλ€λ©΄.......
μ΄κ²μμ μν΄ λ°μ Decontextify.value
λ‘ κ²μ€νΈ κ°μ²΄μ νλ‘ν νμ
μ ν
μ€νΈ instanceOf
. Node.js vm
λͺ¨λμ λ¬Όλ‘ μ΄κ²μ μν₯μλ°μ§ μμ΅λλ€. κ°λν μ¬λμ ν¨μΉλ Proxy
λ₯Ό λ°±λμ΄νμ¬ μλλ°μ€μμ νλ‘μ κ°μ²΄λ₯Ό κ°μ§ν μ μλλ‘ νλ κ²μΌ μ μμ§λ§ μ΄μμ μΈ μ κ·Ό λ°©μμ μλλ°μ€μμ κ°μ²΄μ κΈ°λ₯μ μ λ μ λ’°νμ§ μκ³ contextify.jsλ₯Ό μλλ°μ€μ λ£λ κ²μ
λλ€. κΈ°λ³Έ κ°μ μ¬μ©νμ¬ ν΅μ νκ³ κ²μ€νΈ κ°μ²΄ μ°Έμ‘°λ₯Ό μ²λ¦¬ν©λλ€.
μ¬λλ€μ΄ λ³Ό μ μλλ‘ λΈλΌμ°μ 리μ€λ μμ νλ‘μΈμ€μ λ©μμ§ μ λ¬μ μ¬μ©νμ¬ μ λ’°ν μ μλ μ½λλ₯Ό μ€ννλ μμκ³Ό λνν©λλ€. μ½κ°μ μ€μ μμ
μ΄μ§λ§ μΌλ¨ μλ£λλ©΄ while(1){}
곡격μ λ©΄μμ΄λ©λλ€. μΆμ²λ μ¬κΈ° μ
λλ€.
μ΄ νλ‘μ νΈμ μμ μ μ 체λ₯Ό λ³λλ‘ μμ±νμ§ μλ κ² κ°μ΅λλ€.
OS νλ‘μΈμ€. κ·Έλ μ§ μμΌλ©΄ λ§μ μ루μ
μ μ¬μ©ν μ μμ΅λλ€.
λ μμ ν©λλ€.
κ·Έλ μ§ μμΌλ©΄ ν¨μ¬ λ μμ ν λ§μ μ루μ μ μ¬μ©ν μ μμ΅λλ€.
μ΄λ κ²? NodeJSμμ VM2μ λν λ λμ λμμ΄ μλμ§ νμ€νμ§ μμ΅λλ€. μ μ΄λ μ κ° λ³Έ κ²μ μλλλ€.
μ΄ λΌμ΄λΈλ¬λ¦¬μ κ΄λ¦¬μλ λ¬Έμ #80μμ μ΄ λμμ μ§μ νμ΅λλ€.
https://github.com/laverdet/isolated-vm
λλ μμ§ κ·Έκ²μ μ€μ€λ‘ μλνμ§ μμλ€.
μμ νλ‘μΈμ€μμ μ λ’°ν μ μλ μ½λλ§ μ€νν©λλ€. νΉν λ¨μΌ μ€λ λλΌλ κ²μ μκ³ μλ κ²½μ° κΈ°λ³Έ V8 μΈμ€ν΄μ€μμ μ€νν μνμ΄ μμ΅λλ€.
V8 μμ§μ μ§μ νΈμΆνλ λ¬Έμ λ import λͺ¨λμ΄ μλ€λ κ²μ λλ€. μ κ²½μ°μλ HTTP μμ μ νμ©νκΈ° μν΄ μμ² λͺ¨λμ κ°μ ΈμμΌ ν©λλ€. λν λΉλκΈ°μμ΄μ΄μΌ ν©λλ€.
λλ vm2 + child_processκ° μ’μ μ‘°ν©μ΄λΌκ³ μκ°ν©λλ€.
μΌ,
μ μ @harelmo λ while(1) {}
λ©΄μμ΄ μλ vm2 μμ λΌμ΄λΈλ¬λ¦¬λ₯Ό λ§λ€μμ΅λλ€.
tian-maκ° μΈκΈν κ²κ³Ό μ μ¬νμ§λ§ μμ νλ‘μΈμ€ λμ node.js μμ μ μ€λ λλ₯Ό μ¬μ©ν©λλ€.
https://www.npmjs.com/package/isolated-runtimeμ μ΄ν΄λ³΄κ³ μ¬λ¬λΆμ μκ°μ μλ €μ£ΌμΈμ :)
λ λ€λ₯Έ ν΄κ²° λ°©λ²μ μλ λ°μ€ λ΄μμ Proxy
λΉνμ±ννλ κ²μ
λλ€.
const vm = new VM({
sandbox: {
Proxy: undefined
},
timeout: 100
});
Promiseλ₯Ό μ¬μ©νλ©΄ μκ° μ΄κ³Όλμ§ μλ μ½λλ₯Ό μμ±ν μλ μμ΅λλ€.
"use strict";
const {VM} = require('vm2');
const untrusted = '(' + function(){
Promise.resolve().then(a=>{
while(1){}
});
}+')()';
try{
console.log(new VM({timeout:10}).run(untrusted));
}catch(x){
console.log(x);
}
μ¬κΈ°μ λ¬Έμ λ .thenμ΄ λμ€μ λ§μ΄ν¬λ‘νμ€ν¬ λκΈ°μ΄μμ νΈμΆλ ν¨μλ₯Ό λκΈ°μ΄μ λ£κ² λλ€λ κ²μ
λλ€.
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ €λ©΄ μ체 Promise.then λ° κ΄λ ¨ ν¨μλ₯Ό μμ±νκ±°λ Promiseλ₯Ό λΉνμ±νν΄μΌ ν©λλ€.
λν μ΄κ²μ μλν©λλ€.
const {VM} = require('vm2');
const script = '(' + function() {
(async function x(){
await {then: y=>y()};
while(1){}
})();
}+')()';
new VM({timeout:10}).run(script);
λ°λΌμ Promiseλ₯Ό μ¬μ μνλ κ²λ§μΌλ‘λ μλνμ§ μμ΅λλ€.
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ λ°©λ²μ λͺ¨λ¦
λλ€.
μμ§ μ΄λ € μμ§λ§ READMEμ μ€λͺ μ μΆκ°νμ¬ μ μ¬μ μΈ μ¬μ©μμκ² κ²½κ³ ν΄μΌν©λλ€. μ΄ μ·¨μ½μ μ μλλ°μ€λ₯Ό νμΆν μ μκ² νμ¬ λΌμ΄λΈλ¬λ¦¬μ λͺ©μ μ 무ν¨νν©λλ€.
μΆκ° μ λ³΄κ° μ λ°μ΄νΈλμμ΅λλ€ https://github.com/patriksimek/vm2/commit/77f5265ab53b87864a312156ee62b1082787e9b0#diff -04c6e90faac2675aa89e2176d2eec7d8. κ·Έλ¦¬κ³ μ΄κ²μ΄ μλ λ°μ€λ₯Ό νμΆνλ λ° μ΄λ»κ² μ¬μ©λ μ μλμ§ λͺ¨λ₯΄κ² μ΅λλ€. μ€ν¬λ¦½νΈκ° μ€νλμ΄μΌνλ μλ λ μκ° νλ μ λ§ λ²μ΄λ μ μμ΅λλ€.
μλ§λ μ΄κ²μ μ체 λ¬Έμ μΌ μ μμ§λ§ NodeVMμ΄ "μκ° μ΄κ³Ό"λ₯Ό μ§μνμ§ μλ μ΄μ λ 무μμ λκΉ?
@crowder NodeVMμλ setTimeout, setInterval λ° setImmediateκ° μκΈ° λλ¬Έμ μκ° μ νμ νΌνλ κ²μ΄ μ½μ΅λλ€. λ€λ₯Έ μ΄μ λμμ μ μμ§λ§ NodeVMμ μ¬μ©νμ§ μκ³ VM λ§ μ¬μ©ν©λλ€.
@XmiliaH λ μ΅μν μλνμ§ μμ 무ν 루νλ₯Ό λ°©μ§νλ μκ° μ΄κ³Όλ₯Ό ꡬννμ§ μμ΅λκΉ?
μ
μμ μΈ while (true) + setTimeout μ‘°ν©μ μ¬μ ν ββλ¬Έμ κ° λ μ μμ§λ§ μ€μλ‘ μν λ λ¨μνκ³ μλνμ§ μμ 무ν 루νλ μκ° μ νμ μ§μνμ¬ μ²λ¦¬ ν μ ββμμ΅λλ€.
λ΄ κ΄μ¬μ¬λ NodeVMμ΄ νΈμ€νΈ λͺ¨λμΌ μ μλ λͺ¨λμ μꡬν μ μκ³ μ μ μνλ₯Ό λ³κ²½νλ λμ μκ°μ΄ μ΄κ³Όλλ κ²μ΄ μ’μ§ μμ μ μλ€λ κ²μ
λλ€. λν NodeVMμ λͺ¨λμ λ°ννκ³ μ¬μ©μλ λͺ¨λμ μν΄ λ
ΈμΆλ ν¨μλ₯Ό νΈμΆν κ°λ₯μ±μ΄ λμ§λ§ μκ° μ΄κ³Όλ ν¨μ νΈμΆμ΄ μλ λͺ¨λ λ‘λ©μλ§ μ μ©λ©λλ€.
μκ° μ΄κ³Όκ° μλ ν¨μλ₯Ό νΈμΆνλ €λ©΄ λ€μκ³Ό κ°μ΄ μ§μ ꡬνν μ μμ΅λλ€.
function doWithTimeout(fn, timeout) {
let ctx = CACHE.timeoutContext;
let script = CACHE.timeoutScript;
if (!ctx) {
CACHE.timeoutContext = ctx = vm.createContext();
CACHE.timeoutScript = script = new vm.Script('fn()', {
filename: 'timeout_bridge.js',
displayErrors: false
});
}
ctx.fn = fn;
try {
return script.runInContext(ctx, {
displayErrors: false,
timeout
});
} finally {
ctx.fn = null;
}
}
μ’μ μ§μ @XmiliaH κ·Έλ¦¬κ³ μλ₯Ό λ€μ΄ μ£Όμ
μ κ°μ¬ν©λλ€.
κ·νμ μκ° vm2κ° μλ vm ν¨ν€μ§λ₯Ό μ¬μ©νκ³ μμμ μ μ μμ΅λλ€.
vm2λ₯Ό μ¬μ©ν μ μκ³ μ¬μ ν μκ° μ΄κ³Όν μ μμΌλ©΄ μ’μ κ²μ
λλ€.
@szydan λ΄κ° κ²μν μ½λλ VM2μμ VM μκ°μ μ΄κ³Όνλ λ° μ¬μ©λ©λλ€. NodeVMμλ μκ° μ΄κ³Όκ° μλ κ²½μ° λμΌν κΈ°λ₯μ μ¬μ©ν©λλ€.