Как оценить выражения пользователя в песочнице - PullRequest
7 голосов
/ 06 марта 2012

Я хочу, чтобы мое приложение оценивало выражение от ненадежного пользователя, которое я буду читать из файла JSON. Такие как:

value = "(getTime() == 60) AND isFoo('bar')"

Я нашел много тем об этом здесь, на StackOverflow. Обычно рекомендуется использовать собственный класс Java ScriptEngine, который может читать JavaScript. Или рекомендует пользователю использовать существующую библиотеку, такую ​​как JEXL, MVEL или любую другую из этого списка: http://java -source.net / с открытым исходным кодом / выражение-языки

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

value = "while(true)" // or
value = "new java.io.File(\"R:/t.txt\").delete()" // this works on MVEL

И заблокируйте мое приложение или получите доступ к нежелательным ресурсам.

1) Итак, можно ли легко настроить любую из существующих библиотек, чтобы она могла работать в безопасном месте? «Легко» я имею в виду высокоуровневый API-интерфейс конфигурации, который я бы использовал быстрее, чем написать собственный оценщик выражений. После небольшого количества моих собственных исследований, JEXL и MVEL, похоже, отсутствуют.

2) Или существует существующий язык выражений, который чрезвычайно прост и не может использоваться ненадежным пользователем? Все, что я нашел, очень сложны и реализуют такие вещи, как циклы, операторы импорта и т. Д. Все, что мне нужно, - это анализ математики, логических операторов и моих собственных определенных переменных и методов. Все, что находится за ее пределами, находится за пределами моей компетенции.

3) Если единственное решение - написать собственный оценщик выражений, то где я могу найти руководство по написанию согласованной модели безопасности? Я новичок в этом, и не имею представления о том, какие обычные приемы используются для внедрения кода. Вот почему я хотел избежать написания этого самостоятельно.

1 Ответ

1 голос
/ 01 августа 2012

Я мог бы порекомендовать встраивать Rhino, позволяя пользователю писать javascript.Это соответствует вашим критериям в (2), идеально являясь библиотекой Java, которая позволяет вам запускать javascript (или запускать java из javascript).

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

У вас также есть преимущество в том, что если ваша проблема требует этого, вы вполне можете настроить его так, чтобы те же выражения успешно выполнялись на стороне клиента или сервера.

Дополнительная информацияна встраивание Rhino для достижения того, что вам нужно на http://www.mozilla.org/rhino/tutorial.html#runScript

...