2016-06-06 4 views
1

Я хочу, чтобы клиенты могли отправлять сценарии, которые будут выполняться на сервере. Сценарии будут рассмотрены администраторами до запуска, но я хочу предотвратить катастрофы, если эксплоит не будет обнаружен.Запуск кода клиента на Nodejs в песочнице

Клиент должен использовать только функции, определенные API. Моя стратегия заключалась в том, чтобы создать vm, чтобы создать новый контекст с доступом только к api.

var vm = require('vm'); 

var v = 0; //incremetable via API 

var api = { 
    incr:function(){ 
     v++; 
    } 
} 

var userCode = 
`(function(api){ 
    api.incr(); 
    process.exit();  //ERROR: process is undefined 
})`; 

vm.runInNewContext(userCode)(api); 

console.log(v); 

В теории это выглядит нормально. Тем не менее, оказывается, что вы можете разбить сервер через

api.incr.constructor("return this")().process.exit(1)


Как я мог бы предложить API (так называемый потенциал сценария для изменения основного контекста) без ущерба для моего сервера?

Нечто похожее на iframe в браузере.

+0

Привязать все функции к этому из var 'api' – MayorMonty

+0

Это очень сложная задача из-за характера JavaScript. Я считаю, что это можно сделать, но вы должны быть очень осторожны, чтобы избежать утечки объектов cross-VM, и я никогда не видел, чтобы кто-то еще реализовал это безопасно. Другие виды атак также по-прежнему возможны, как и потребление всей памяти. –

ответ

0

Вы можете изменить функцию this, используя .bind. Например:

var api = { 
    incr: (function() { 
     return v++; 
    }).bind(api) 
} 

Обратите внимание, что это не проверено. Вероятно, есть способы подорвать такой метод, но это предотвратит некоторые атаки. Как правило, это плохая идея запускать код пользователя на вашем сервере, в первую очередь, VM или нет. На самом деле я очень удивлен тем, что узел разрешил такую ​​ошибку. Возможно, неплохо было бы опубликовать отчет об ошибке.

+0

Идея хорошая, но этого будет недостаточно. Я добавил 'api.incr.constructor = null; api.incr.bind (null); 'и, похоже, выполняет эту работу. – RainingChain

+0

О запуске клиентского кода, он больше похож на проект github и принимает вклады от других. Это эквивалентно запуску кода пользователя после утверждения. – RainingChain

+0

Надеюсь, у вас есть успех в вашем проекте. Удачи! :) – MayorMonty

Смежные вопросы