Как запустить Javascript с помощью Rhino для Java в «песочнице»?

StackOverflow https://stackoverflow.com/questions/93911

Вопрос

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

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

  • Необходимо защититься от бесконечных циклов
  • Остерегайтесь создания новых тем.
  • Ограничить доступ к сервисам и среде
    • Файловая система (Пример:Если недовольный сценарист решил удалить файлы)
    • База данных (то же самое, что и удаление записей базы данных)

По сути, мне нужно настроить область javascript так, чтобы она включала только то, что им нужно, и не более того.

Это было полезно?

Решение

Чтобы защититься от бесконечных циклов, вам придется поместить его в отдельный процесс, чтобы его можно было завершить.

Чтобы защититься от создания потоков, вам необходимо расширить SecurityManager (реализация по умолчанию позволяет ненадежному коду получать доступ к группам потоков, не являющимся корневыми).

Безопасность Java позволяет предотвратить доступ к файловой системе.

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

Редактировать:Я должен отметить, что в версии Rhino, поставляемой с JDK6, была проведена работа по обеспечению безопасности, но в нее не включен компилятор.

Другие советы

Чтобы избежать бесконечных циклов, вы можете наблюдать за количеством инструкций во время выполнения сценария (это работает только с интерпретируемыми сценариями, а не с скомпилированными).

Есть это пример в JavaDocs Rhino чтобы предотвратить запуск скрипта более десяти секунд:

 protected void observeInstructionCount(Context cx, int instructionCount)
 {
     MyContext mcx = (MyContext)cx;
     long currentTime = System.currentTimeMillis();
     if (currentTime - mcx.startTime > 10*1000) {
         // More then 10 seconds from Context creation time:
         // it is time to stop the script.
         // Throw Error instance to ensure that script will never
         // get control back through catch or finally.
         throw new Error();
     }
 }

Чтобы заблокировать доступ к классам и методам Java, посмотрите...

http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/

Я только что наткнулся на этот пост в блоге, который кажется полезным для более или менее песочницы чего угодно (не только Rhino):

http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html

Если вам нужны только чистые функции JavaScript, вот решение на основе встроенной библиотеки Rhino JDK без импорта каких-либо сторонних библиотек:

  1. Узнайте имя класса фабрики движка сценариев JavaScript с помощью ScriptEngineManager#getEngineFactories
  2. Загрузите класс фабрики механизма сценариев в новый загрузчик классов, в котором JavaMembers или другие связанные классы будут игнорироваться.
  3. Вызовите #getScriptEngine на загруженной фабрике обработчика сценариев и проверьте сценарии на возвращенном обработчике сценариев.

Если данный сценарий содержит сценарий Java, загрузчик классов попытается загрузить JavaMembers или другие классы и вызвать исключение «Класс не найден».Таким образом, вредоносные скрипты будут игнорироваться без выполнения.

Пожалуйста, прочитайте файлы ConfigJSParser.java и ConfigJSClassLoader.java для получения более подробной информации:

https://github.com/webuzz/simpleconfig/tree/master/src/im/webuzz/config

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top