Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

В этом примере в Rhino JavaDocs предотвращается запуск script более десяти секунд:

 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();
     }
 }

Ответ 5

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

  • Найти JavaScript script engine factory имя класса с помощью ScriptEngineManager # getEngineFactories
  • Загрузите класс script engine factory в новый загрузчик классов, в котором будут игнорироваться JavaMembers или другие связанные классы.
  • Вызов #getScriptEngine в загруженном script engine factory и eval скриптах на возвращенном script двигателе.

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

Подробнее читайте файлы ConfigJSParser.java и ConfigJSClassLoader.java:

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

Ответ 6

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