2008-10-03 9 views
13

Quiero poder ejecutar el código ruby ​​no confiable. Quiero poder pasar variables a dicho código no confiable que pueda usar. También quiero que dicho código me devuelva un resultado. Aquí está un ejemplo conceptual de lo que estoy pensando¿Cómo ejecutar el código de Ruby que no es de confianza dentro de un entorno seguro?

input = "sweet" 
output = nil 
Thread.start { 
    $SAFE = 4 
    #... untrusted code goes here, it uses the input variable(s) 
    #to calculate some result that it places in the output variable 
} 
#parse the output variable as a string. 

Solo para aclarar, básicamente estoy usando el código no confiable como una función. Quiero proporcionar algunas entradas, y luego permitir que escriba en la salida. Eso es todo lo que realmente quiero, no me importa cómo se hace, solo quiero la capacidad de usar código Ruby no confiable como una especie de función. La solución no tiene que parecerse en nada al código que escribí arriba, solo lo estoy usando para ilustrar lo que quiero.

Ahora bien, actualmente se puede pensar en 3 maneras de hacer esto:

  1. utilizar el nivel seguro $ constructo anterior.
  2. whytheluckystiff tiene un complemento de Sandbox para ruby ​​
  3. Podría ejecutar cada función en su propia máquina virtual, utilizando algún tipo de software de virtualización de os como vmware o Xen o algo así.

Me pregunto si alguien tiene alguna recomendación para ejecutar el código ruby ​​no confiable de una manera funcional? ¿Qué opción recomendarías? ¿Cómo lo harías? Gracias.

Respuesta

12

$ SAFE no es suficiente; necesitas estar al menos al nivel de la caja de arena de Why's freaky. Sin embargo, no sé si ese código de sandbox se mantiene activamente o si alguna vez resolvió los agujeros como bucles infinitos, etc.

Inseguro generalmente significa hostil. Si puedes relajarte de hostil a, digamos, "ingenuo", y dependiendo de los requisitos de tu aplicación, puedes salirte con Sandboxing en Ruby. No es realmente un escenario de primera clase en el diseño del lenguaje.

Incluso con eso, sin embargo, probablemente no necesite ir al nivel de separación de la máquina. Me sentiría bastante seguro al usar un sandbox en un proceso generado por separado, con tu aplicación funcionando como un administrador de procesos para matar a cualquiera que logre colgar/encender. Ahora, eso es unos pocos órdenes de magnitud más de trabajo que tu simple bloque anterior.

Pero recuerda y sigue repitiendo, "SAFE no puede tratar con hostil".

+3

¿Alguien tiene alguna referencia que explique qué le pasa a $ SAFE? – sheldonh

3

Recomiendo usar JRuby.

La JVM ha tenido un modelo de seguridad muy sólido incorporado desde el principio, y JRuby se aprovecha de eso. Puede restringir el acceso a archivos, restringir la carga de código y mucho más. Es ahora mejor que todo lo que existe en Rubls impls nativas, y hay una serie de sitios que ejecutan sitios de espacio aislado accesibles para el usuario en JRuby para este propósito.

+0

+1, pero para el registro, JRuby actualmente no implementa completamente '$ SAFE', ¿o sí? –

+0

No, no lo hacemos, principalmente porque los cheques deben estar salpicados en toda la base de códigos, y casi no hay forma de probar que usted haya cubierto todo. Me gustaría redefinir los niveles SEGUROS en términos de políticas de seguridad JVM, ya que no tendríamos verificaciones manuales para hacer cumplir en ese momento. –

3

$SAFE no lo protege de todo lo que un pirata informático malintencionado podría hacer.

Después de haber seguido este camino (ver Ruby: creating a sandboxed eval?), seguí los consejos de los comentaristas e incrustó un intérprete específico de la aplicación que me dio control completo sobre lo que podía y no podía hacerse (ver Ruby: looking for ruby-embeddable interpreter or scripting language).

Resultó ser increíblemente fácil de usar atraco a mano armada (como menos de una hora de la descarga de la gema a un intérprete personalizado) - ver https://github.com/jcoglan/stickup

1

creé una joya llamada 'confianza-cajón de arena' que se ejecuta el código Ruby dentro de un contenedor Docker completamente controlado. Puede desactivar la red, establecer cuotas de disco, limitar el tiempo de ejecución, equilibrar la CPU con otros contenedores en ejecución, establecer límites de memoria, etc. Y la sobrecarga es bastante baja.

Puede leer más sobre esto aquí: https://github.com/vaharoni/trusted-sandbox

Déjame saber lo que piensa!

Cuestiones relacionadas