2015-10-13 2 views
5

Я работаю над react-metaform, и одной из моих задач является то, что мне нужно разрешить конечному пользователю определять метаданные как функции. Пример:Как проверить, является ли функция чистой?

socialSecurityNumber.required: (m) => m.type == 'person' 

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

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

Вопрос: Как я могу убедиться, что пользовательская функция выполняет только его параметры и ничего больше?

+3

Я полагаю, ваш лучший выбор, чтобы определить свой собственный язык выражений, который разбирается и затем оценивается на ваших реальных объектах, а не с помощью 'new Function'. – Bergi

+2

http://stackoverflow.com/questions/14889393/how-to-run-a-javascript-function-in-a-sandbox-environment – epascarello

+2

Я думаю, что с того момента, как вы просите пользователя написать JS и выполнить его в значительной степени сделаны для. Вы не можете предотвратить длительное время выполнения (выполнить до завершения, да!) Или убедиться, что функция чистая (возможно, с массивным затенением параметров, но это было бы странно). –

ответ

1

Я бы использовал esprima для анализа функций JavaScript пользователей, которые хранятся в файлах или в базе данных. И я бы разрешил запускать только код, который проходит тест синтаксического анализа (только whitelisted features - с использованием локальных переменных, параметров, ...).

Вы можете начать с очень простого кода проверки, который позволяет использовать очень ограниченные скрипты и постепенно улучшать его. Тем не менее, я думаю, вы будете прилагать много усилий для решения с течением времени, потому что ваши пользователи всегда захотят больше.


Примечание: Angular.js использует для инъекций его зависимостей такого рода «трюк»: https://jsfiddle.net/987Lwezy/

function test() { 
    console.log("This is my secret!"); 
} 


function parser(f) { 
    document.body.innerHTML = test.toString(); 
} 

parser(test); 
+0

Хм, как это предотвратит что-то вроде функции() {[] .__ proto __. Slice = function() {return «Я прикрепил вас к приложению!»; }; } '(в котором нет свободных переменных)? – Bergi

+0

OP сказал, что хочет разрешить доступ только к пользовательским параметрам. Назначение '[] .__ proto __. Slice' не является назначением пользовательского параметра. –

+0

По сути, вам нужно либо подобрать подмножество JavaScript, что вы разрешаете или выбираете другое решение. Крайне важно использовать «белое решение», а не «решение черного списка». Я имею в виду, что вы не можете просто запретить «eval» и надеяться на лучшее. Вы можете включить только базовую арифметику с параметрами функции ... для всех, кого я знаю, это может быть достаточно в некоторых сценариях. –

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