Безопасность с помощью сценариев Java (JRuby, Jython, Groovy, BeanShell и т. Д.)

Я хочу запустить несколько непроверенных сценариев (написанных на языке, который еще предстоит определить, но должен быть основан на Java, поэтому кандидатами являются JRuby, Groovy, Jython, BeanShell и т. Д.). Я хочу, чтобы эти скрипты могли делать одни вещи и были ограничены в других делах.

Обычно я бы просто использовал Java SecurityManager и покончил с этим. Это довольно просто и позволяет мне ограничивать доступ к файлам и сети, возможность выключения JVM и т. Д. И это хорошо работает для вещей высокого уровня, которые я хочу заблокировать.

Но есть кое-что, что я хочу разрешить, но только через свой собственный API / библиотеку, которую я предоставил. Например, я не хочу разрешать прямой доступ к сети для открытия URLConnection на yahoo.com, но я в порядке, если это будет сделано с MyURLConnection. То есть - есть набор методов / классов, которые я хочу разрешить, а затем все остальное, что я хочу запретить.

Я не верю, что этот тип безопасности может быть реализован с помощью стандартной модели безопасности Java, но, возможно, это возможно. У меня нет особых требований к производительности или гибкости самого языка сценариев (сценарии будут простыми процедурными вызовами моего API с базовым циклом / ветвлением). Так что даже «большие» накладные расходы, связанные с проверкой безопасности при каждом вызове отражения, меня устраивают.

Предложения?


person Patrick Lightbody    schedule 09.02.2009    source источник


Ответы (3)


Отказ от ответственности: я не являюсь экспертом по API-интерфейсам безопасности Java, поэтому может быть лучший способ сделать это.

Я работаю в Alfresco, корпоративной CMS с открытым исходным кодом на основе Java, и мы реализовали нечто похожее на то, что вы описываете. Мы хотели разрешить создание сценариев, но только для того, чтобы предоставить механизму сценариев доступ к подмножеству наших API-интерфейсов Java.

Мы выбрали Rhino Engine для написания сценариев JavaScript. Он позволяет вам контролировать, какие API доступны для JavaScript, что позволяет нам выбирать, какие классы доступны, а какие нет. Накладные расходы, по словам наших инженеров, порядка 10% - неплохо.

В дополнение к этому, и это также может иметь отношение к вам, на стороне Java мы используем Acegi (теперь Spring Security) и используем АОП, чтобы дать ролевой контроль над тем, какие методы может вызывать определенный пользователь. Это очень хорошо работает для авторизации. Таким образом, пользователь, обращающийся к нашему приложению через JavaScript, сначала имеет ограниченный API, доступный ему, а затем этот API может быть ограничен еще больше на основе авторизации. Таким образом, вы можете использовать методы АОП для дальнейшего ограничения того, какие методы могут быть вызваны, что позволит раскрыть это на других языках сценариев, таких как Groovy и т. Д. API защищают пользователей от несанкционированного доступа.

person Jean Barmash    schedule 09.02.2009
comment
Спасибо, это действительно полезно. Кстати, для меня вариант использования - разрешить людям загружать сценарии для своих нагрузочных тестов для запуска на browsermob.com. Я не смотрел на Rhino, но похоже, что он может работать, пока не разрешает прямой доступ к API Java, как это делает Groovy. - person Patrick Lightbody; 10.02.2009
comment
Да, там у вас больше контроля, и это хорошо с точки зрения безопасности. Возможно, вам придется создать оболочки для определенных API, а затем предоставить эти объекты. Например, у нас есть механизм рабочего процесса, и мы создали объект рабочего процесса, который затем предоставили JavaScript, который контролирует, что вы можете делать. - person Jean Barmash; 10.02.2009
comment
Быстрое наблюдение: как вы убедились, что переменная Packages недоступна? См. codeutopia.net/blog/2009/01/02/ песочница-носорог-в-Java - person Patrick Lightbody; 10.02.2009

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

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

Вам необходимо убедиться, что сам скриптовый движок безопасен. Версия Rhino в Sun JDK должна быть в порядке, но никаких гарантий. Очевидно, вам нужно убедиться, что все, что доступно для сценария, безопасно.

person Tom Hawtin - tackline    schedule 09.02.2009
comment
Том - спасибо за советы. Похоже, мне также нужно немного больше изучить модель безопасности Java - я не знал о doPriveleged - person Patrick Lightbody; 10.02.2009

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

http://www.chrismoos.com/2010/03/24/groovy-scripts-and-jvm-security/

person sulai    schedule 12.02.2014