tutorial - ¿Cómo se puede ejecutar Javascript usando Rhino para Java en un sandbox?
rhino javascript (6)
Parte de nuestra aplicación java necesita ejecutar javascript escrito por no desarrolladores. Estos no desarrolladores están usando javascript para el formato de datos. (Lógica simple y concatenación de cadenas principalmente).
Mi pregunta es cómo puedo configurar la ejecución de estos scripts para asegurarme de que los errores de scripting no tengan un gran impacto negativo en el resto de la aplicación.
- Necesidad de protegerse contra bucles infinitos
- Protéjase contra el engendramiento de nuevos hilos.
- Limitar el acceso a los servicios y el entorno
- Sistema de archivos (Ejemplo: si un guionista disgustado decidió eliminar archivos)
- Base de datos (Lo mismo que borrar registros de la base de datos)
Básicamente, necesito configurar el alcance de JavaScript para que solo incluya exactamente lo que necesitan y nada más.
Javascript es de un solo subproceso y no puede acceder al sistema de archivos, por lo que no creo que tengas que preocuparte por eso. No estoy seguro de si hay alguna manera de establecer un tiempo de espera para protegerse de los bucles infinitos, pero siempre podría engendrar un hilo (Java) que ejecute el script y luego matar el hilo después de tanto tiempo.
Para bloquear el acceso a clase y método Java, eche un vistazo a ...
http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/
Acabo de encontrar esta publicación de blog que parece ser útil para sandboxing más o menos cualquier cosa (no solo Rhino):
http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html
Para protegerse contra bucles infinitos, necesitaría ponerlo en un proceso separado para poder matarlo.
Para evitar crear subprocesos, debe extender SecurityManager (la implementación predeterminada permite que el código que no es de confianza acceda a grupos de subprocesos no raíz).
La seguridad de Java le permite evitar el acceso al sistema de archivos.
Para las restricciones de la base de datos, es posible que pueda usar la seguridad del usuario SQL estándar, pero eso es bastante débil. De lo contrario, debe proporcionar una API que aplique sus restricciones.
Editar: Debo señalar que la versión de Rhino provista con JDK6 ha tenido un trabajo de seguridad, pero no incluye el compilador.
Para protegerse de los bucles infinitos, puede observar el recuento de instrucciones a medida que se ejecuta el script (esto funciona solo con scripts interpretados, no con los compilados).
Hay un ejemplo en Rhino JavaDocs para evitar que un script se ejecute por más de diez segundos:
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();
}
}
Si solo busca funciones de JavaScript puro, aquí hay una solución basada en la biblioteca de Rhino incorporada de JDK sin importar ninguna biblioteca de terceros:
- Descubra el nombre de la clase de fábrica del motor de script JavaScript mediante ScriptEngineManager # getEngineFactories
- Cargue la clase de fábrica del motor de scripts en un nuevo cargador de clases, en el que JavaMembers u otras clases relacionadas se ignorarán.
- Llame a #getScriptEngine en fábrica de motores de scripts cargados y scripts eval en el motor de script devuelto.
Si la secuencia de comandos dada contiene una secuencia de comandos Java, el cargador de clases intentará cargar JavaMembers u otras clases y desencadenará excepciones de clase no encontradas. De esta forma, las secuencias de comandos maliciosas se ignorarán sin ejecución.
Lea los archivos ConfigJSParser.java y ConfigJSClassLoader.java para obtener más detalles:
https://github.com/webuzz/simpleconfig/tree/master/src/im/webuzz/config