Безопасность с Java-скриптами (JRuby, Jython, Groovy, BeanShell и т.д.)
Я хочу запустить некоторые не проверенные сценарии (написанные на языке, который еще не определен, но должен быть основан на Java, поэтому JRuby, Groovy, Jython, BeanShell и т.д. - все кандидаты). Я хочу, чтобы эти скрипты могли делать что-то и ограничивались другими делами.
Обычно я просто использую Java SecurityManager и делаю это с ним. Это довольно просто и позволяет мне ограничивать доступ к файлам и сети, возможность отключения JVM и т.д. И это будет хорошо работать для материала высокого уровня, который я хочу заблокировать.
Но есть некоторые вещи, которые я хочу разрешить, но только через мой пользовательский API/библиотеку, которую я предоставляю. Например, я не хочу разрешать прямой доступ к сети, чтобы открыть URLConnection на yahoo.com, но я в порядке, если это делается с MyURLConnection. То есть - существует набор методов/классов, которые я хочу разрешить, а затем все остальное, что я хочу быть вне пределов.
Я не считаю, что этот тип безопасности можно сделать со стандартной моделью безопасности Java, но, возможно, это возможно. У меня нет особых требований к производительности или гибкости самого языка сценариев (скрипты будут простыми процедурными вызовами для моего API с базовым циклом/ветвлением). Таким образом, даже "большие" накладные расходы, которые проверяют проверку безопасности на каждый вызов отражения, мне в порядке.
Предложения?
Ответы
Ответ 1
Отказ от ответственности: я не являюсь экспертом в API безопасности Java, поэтому может быть лучший способ сделать это.
Я работаю для Alfresco, Java-based Open Source Enterprise CMS, и мы реализовали нечто похожее на то, что вы описали. Мы хотели разрешить создание сценариев, но только для того, чтобы показать подмножество наших API Java для механизма сценариев.
Мы выбрали Rhino Engine для сценариев JavaScript. Это позволяет вам контролировать, какие API-интерфейсы подвержены JavaScript, что позволяет нам выбирать, какие классы доступны, а какие нет. Накладные расходы, по словам наших инженеров, составляют порядка 10% - не так уж плохо.
В дополнение к этому, и это может быть актуально и для вас, на стороне Java, мы используем Acegi (теперь Spring Security) и используем AOP, чтобы предоставить контроль на основе ролей, по каким методам может быть определен определенный пользователь вызов. Это очень хорошо подходит для авторизации. Таким образом, в действительности пользователь, обращающийся к нашему приложению через JavaScript, сначала имеет ограниченный API, доступный ему, в первую очередь, а затем этот API может быть ограничен еще более на основе авторизации. Таким образом, вы можете использовать методы АОП для дальнейшего ограничения того, какие методы могут быть вызваны, что позволяет выявить это на других языках сценариев, таких как Groovy и т.д. Мы также добавляем их, имея уверенность в том, что наши лежащие в основе Java API, защищают пользователей от несанкционированного доступа.
Ответ 2
Возможно, вы сможете использовать пользовательский загрузчик классов, который ветеринары связывают с классами, прежде чем делегировать его родителям.
Вы можете создавать свои собственные разрешения, проверять те, которые находятся в ваших чувствительных к безопасности API, а затем использовать AccessController.doPrivileged
для восстановления соответствующих привилегий при вызове базового API.
Вам нужно убедиться, что сам скриптовый движок защищен. Версия Rhino в Sun JDK должна быть в порядке, но никаких гарантий. Очевидно, что вам нужно убедиться, что все, доступное для script, безопасно.
Ответ 3
В Groovy вы можете сделать то, что вы упомянули. На самом деле очень легко. Вы можете легко ограничить разрешения ненадежных скриптов, работающих в надежной среде, разрешить использование собственного api, что, в свою очередь, может сделать недоверенные вещи.
http://www.chrismoos.com/2010/03/24/groovy-scripts-and-jvm-security/