2009-02-09 9 views
11

Estoy buscando ejecutar algunas secuencias de comandos no verificadas (escritas en un lenguaje aún por determinar, pero debe estar basado en Java, entonces JRuby, Groovy, Jython, BeanShell, etc. son todos candidatos). Quiero que estos scripts puedan hacer algunas cosas y restringirse de hacer otras cosas.Seguridad con Java Scripting (JRuby, Jython, Groovy, BeanShell, etc.)

Normalmente, utilizaré el SecurityManager de Java y terminaré con él. Eso es bastante simple y me permite restringir el acceso a archivos y redes, la capacidad de apagar la JVM, etc. Y eso funcionará bien para las cosas de alto nivel que quiero bloquear.

Pero hay algunas cosas que quiero permitir, pero solo a través de mi API/biblioteca personalizada que he proporcionado. Por ejemplo, no quiero permitir el acceso directo a la red para abrir una URLConnection a yahoo.com, pero estoy de acuerdo si se hace con MyURLConnection. Es decir, hay un conjunto de métodos/clases que quiero permitir y luego todo lo demás que quiero que esté fuera de los límites.

No creo que este tipo de seguridad se pueda hacer con el modelo de seguridad estándar de Java, pero quizás sí. No tengo un requisito específico de rendimiento o flexibilidad en el lenguaje de scripts en sí (los scripts serán simples llamadas de procedimiento a mi API con bucle/ramificación básica). Así que incluso una sobrecarga "grande" que verifique un control de seguridad en cada llamada de reflexión está bien para mí.

Sugerencias?

Respuesta

4

Descargo de responsabilidad: No soy un experto en las API de seguridad de Java, por lo que puede haber una mejor manera de hacerlo.

Trabajo para Alfresco, Open Source Enterprise CMS basado en Java, e implementamos algo similar a lo que describes. Queríamos permitir secuencias de comandos, pero solo para exponer un subconjunto de nuestras API de Java para el motor de secuencias de comandos.

Elegimos Rhino Engine para JavaScript scripting. Le permite controlar qué API están expuestas a JavaScript, lo que nos permite elegir qué clases están disponibles y cuáles no. La sobrecarga, de acuerdo con nuestros ingenieros, es del orden del 10%, no está mal.

Además de esto, y esto puede ser relevante para usted también, en el lado de Java, utilizamos Acegi (ahora Spring Security) y usamos AOP para dar control basado en roles sobre qué métodos puede llamar un determinado usuario . Eso funciona bastante bien para la autorización. Entonces, en efecto, un usuario que accede a nuestra aplicación a través de JavaScript primero tiene una API restringida disponible para él, y esa API puede restringirse aún más en función de la autorización. Por lo tanto, podría utilizar las técnicas AOP para restringir aún más los métodos que se pueden llamar, lo que permite exponer esto en otros lenguajes de scripts, como Groovy, etc. Estamos en el proceso de agregar esos también, teniendo la confianza de que nuestro Java subyacente Las API protegen a los usuarios del acceso no autorizado.

+0

Gracias - eso es realmente útil. Por cierto, el caso de uso para mí es permitir que las personas carguen scripts para que se ejecuten sus pruebas de carga en http://browsermob.com. No había mirado a Rhino, pero parece que podría funcionar, siempre y cuando no permita el acceso directo a las API de Java, como lo hace Groovy. –

+0

Sí, tienes más control allí, lo cual es bueno desde la perspectiva de la seguridad. Puede que tenga que crear envoltorios para ciertas API y luego exponer esos objetos. Por ejemplo, tenemos un motor de flujo de trabajo y creamos un objeto de flujo de trabajo que luego expusimos a JavaScript, que controla lo que puede hacer. –

+0

Seguimiento rápido: ¿cómo se aseguró de que la variable Packages no fuera accesible? Ver http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/ –

3

Es posible que pueda usar un cargador de clases personalizado que hace que los veterinarios se vinculen a las clases antes de delegar en sus padres.

Puede crear sus propios permisos, buscar aquellos en sus API sensibles a la seguridad y luego usar AccessController.doPrivileged para restaurar los privilegios apropiados mientras llama a la API subyacente.

Debe asegurarse de que el motor de scripts sea seguro. La versión de Rhino in the Sun JDK debería estar bien, pero no hay garantías. Obviamente, debe asegurarse de que todo lo disponible para el script sea seguro.

+0

Tom - gracias por los consejos. Parece que también necesito investigar el modelo de seguridad de Java un poco más: no estaba al tanto de doPriveleged –

0

En Groovy, puede hacer exactamente lo que ha mencionado. En realidad es muy fácil. Puede limitar fácilmente los permisos de secuencias de comandos no confiables que se ejecutan en un entorno confiable, permitir el uso de su propia API, que a su vez puede hacer cosas que no son de confianza.

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

Cuestiones relacionadas