2012-03-05 10 views
6

Quiero que mi aplicación evalúe una expresión de un usuario que no es de confianza, que leeré de un archivo JSON. Tales como:Cómo evaluar expresiones de usuario en un sandbox

value = "(getTime() == 60) AND isFoo('bar')" 

He encontrado muchos hilos sobre esto aquí en StackOverflow. Por lo general, se recomienda utilizar la clase ScriptEngine propia de Java, que puede leer JavaScript. O recomendar al usuario si desea utilizar una biblioteca existente como JEXL, MVEL, o cualquier otro de esta lista: http://java-source.net/open-source/expression-languages

Pero todos parecen depender de un usuario de confianza (ej .: un archivo de configuración se escribe a sí mismo ya quiero hacer algunas secuencias de comandos en él). Pero en mi caso, quiero que mi evaluación de expresión se ejecute en un entorno seguro. Por lo que el usuario no puede hacer algo tan simple como:

value = "while(true)" // or 
value = "new java.io.File(\"R:/t.txt\").delete()" // this works on MVEL 

Y encerrar a mi aplicación, o acceder a los recursos deseados.

1) ¿Alguna de esas bibliotecas existentes puede configurarse fácilmente para que pueda ejecutarse en una caja fuerte? Por 'fácil', me refiero a la API de configuración de alto nivel que me resultaría más rápida de usar que escribir mi propio evaluador de expresiones. Después de hacer un poco de mi propia investigación, tanto JEXL como MVEL parecen estar fuera.

2) ¿O existe un lenguaje de expresiones existente que es extremadamente simple para que no pueda ser explotado por un usuario no confiable? Todos los que encontré son muy complejos e implementan cosas como bucles, instrucciones de importación, etc. Todo lo que necesito es analizar los operadores matemáticos, lógicos y mis propias variables y métodos definidos. Cualquier cosa más allá está fuera de mi alcance.

3) Si la única solución es escribir mi propio evaluador de expresiones, ¿dónde puedo encontrar orientación sobre cómo escribir un modelo de seguridad coherente? Soy nuevo en esto, y no tengo idea de cuáles son los trucos más comunes utilizados para la inyección de código. Por eso quería evitar tener que escribir esto por mi cuenta.

+1

Puede haber algo de información útil a partir de la siguiente pregunta (que se ocupa de la situación un poco más difícil de código Java no de confianza): http://stackoverflow.com/questions/9041246/what-are-the-security-risks-i-should-guard-against-when-running-user-supplied-ja/9041423 # 9041423 – DNA

+0

¿Alguna vez recibió una respuesta a esta pregunta? – ccleve

+0

Nada que me satisfaga. Decidí construirlo solo y aprenderlo a medida que avanzo. – VIBrunazo

Respuesta

1

Podría recomendar incrustar Rhino, permitiendo al usuario escribir javascript. Se ajusta a sus criterios en (2) perfectamente una biblioteca java que le permite ejecutar javascript (o ejecutar java desde javascript).

Configura un contexto y el usuario solo tiene acceso a lo que coloca en el contexto o hace que sea accesible desde él. Las expresiones de JavaScript pueden ser tan simples como el caso más simple que muestra arriba, o pueden ser tan complejas como lo necesiten. Incrustar Rhino y exponer un conjunto limitado de objetos fue una gran manera de habilitar todo tipo de secuencias de comandos en un proyecto anterior, y eso fue hace algunos años. Rhino ya es bastante maduro.

También tiene la ventaja de que si su problema lo requiere, es posible que pueda configurarlo para que las mismas expresiones funcionen felizmente en el lado del cliente o del servidor.

Más información sobre la incorporación de Rhino para lograr lo que necesita en http://www.mozilla.org/rhino/tutorial.html#runScript

Cuestiones relacionadas