Как оценить выражения пользователя в песочнице

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

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

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

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

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

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

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

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

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

1 ответ

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

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

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

Дополнительную информацию о встраивании Rhino для выполнения своих задач можно найти по адресу http://www.mozilla.org/rhino/tutorial.html.

Другие вопросы по тегам