Защита определяемой пользователем функции JavaScript для защиты сервера node.js. - PullRequest
3 голосов
/ 06 апреля 2019

Я создаю веб-страницу для обучения математике (серверная часть NodeJS и угловой интерфейс). Я хочу, чтобы особый вид пользователей (создатель) создавал математические упражнения. Одно из этих упражнений может выглядеть так:

Marie has ${nums[0]} oranges and ${nums[1]} apples. How many fruits does she have?

Теперь я хочу, чтобы создатель написал функцию генерации чисел, такую ​​как:

const generate = () => {
  const nums = new Array(2).fill(0).map(e => Math.floor(Math.random() * 10)
  return { nums: nums, answer: nums.reduce((p, c) => p + c, 0) }
}

Эта функция должна быть отправлена ​​на сервер и сохранена. Когда пользователь хочет попробовать тест, вопрос должен быть выполнен на сервере. Что я должен сделать, чтобы защитить сервер от вредоносного кода, например:

const generate = () => {
  process.exit()
}

Ответы [ 2 ]

2 голосов
/ 06 апреля 2019

Действительно короткий ответ, это никогда не является безопасным для сервера. Невозможно доказать, что программа безопасна. Существуют смягчающие меры, такие как песочница, которая помогает, но в конечном итоге это всегда риск. Для этого приложения, возможно, ненужный.

Рассмотрим способ передачи формулы, который не требует exec. Одним из способов может быть отправка какого-либо абстрактного синтаксического дерева или синтаксический анализ математического выражения.

Этот пакет npm выглядит многообещающим. Заполните шаблон строки математического выражения так же, как заполните шаблон письменного вопроса. Возможно, потребуется предоставить другой объект, чтобы определить, какие случайные числа нужны, и сопоставить их с именами для использования в шаблонах. math-expression-evaluator

0 голосов
/ 06 апреля 2019

Это не будет безопасно для сервера / клиента.

Не уверен, что это правильный путь или нет. но вы можете ограничить доступ к глобальным переменным

const generate1 = () => {
    process.exit();
}

const generate2 = () => {
    const nums = new Array(2).fill(0).map(e => Math.floor(Math.random() * 10));
    return {
        nums: nums,
        answer: nums.reduce((p, c) => p + c, 0)
    }
}

const funcStr1 = generate1.toString();
const funcStr2 = generate2.toString();

//get all global variables key from 'global' and check it exist or not
// const globals = Object.keys(global); // will return same result as below remove keys which you want to allow
const globals = ['DTRACE_NET_SERVER_CONNECTION',
    'DTRACE_NET_STREAM_END',
    'DTRACE_HTTP_SERVER_REQUEST',
    'DTRACE_HTTP_SERVER_RESPONSE',
    'DTRACE_HTTP_CLIENT_REQUEST',
    'DTRACE_HTTP_CLIENT_RESPONSE',
    'COUNTER_NET_SERVER_CONNECTION',
    'COUNTER_NET_SERVER_CONNECTION_CLOSE',
    'COUNTER_HTTP_SERVER_REQUEST',
    'COUNTER_HTTP_SERVER_RESPONSE',
    'COUNTER_HTTP_CLIENT_REQUEST',
    'COUNTER_HTTP_CLIENT_RESPONSE',
    'global',
    'process',
    'Buffer',
    'clearImmediate',
    'setImmediate',
    // 'clearInterval',
    // 'clearTimeout',
    // 'setInterval',
    // 'setTimeout'
];

const hasGlobal1 = globals.some((g) => funcStr1.includes(`${g}.`));
const hasGlobal2 = globals.some((g) => funcStr2.includes(`${g}.`));

console.log('generate1 has global', hasGlobal1);
console.log('generate2 has global', hasGlobal2);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...