2010-12-01 18 views
9

Actualmente estoy intentando escribir Sandbox para ejecutar código Java no confiable. La idea es aislar la aplicación Java del acceso al sistema de archivos o los sockets de red. La solución que tengo en este momento es reescribir SecurityManager, que prohíbe cualquier acceso a IO o red.Caja de arena de Java. Uso de SecurityManager para redirigir el acceso de E/S

Ahora quiero no lo quiera, pero para redirigir las llamadas al sistema de archivos, es decir, si la aplicación quiere escribir a "/home/user/application.txt" la ruta del archivo debe ser reemplazado con algo como "/temp/trusted_folder/application.txt". Así que, básicamente, quiero permitir que las aplicaciones accedan al sistema de archivos solo en una carpeta particular y redireccionar todas las demás llamadas a esta carpeta.

Así que aquí está el método de la clase FileOutputStream, donde se pregunta a SM, si hay un permiso para escribir en la ruta determinada.

public FileOutputStream(File file, boolean append) 
    throws FileNotFoundException 
{ 
    String name = (file != null ? file.getPath() : null); 
    SecurityManager security = System.getSecurityManager(); 
    if (security != null) { 
     security.checkWrite(name); 
    } 
    if (name == null) { 
     throw new NullPointerException(); 
    } 
    fd = new FileDescriptor(); 
    fd.incrementAndGetUseCount(); 
    this.append = append; 
    if (append) { 
     openAppend(name); 
    } else { 
     open(name); 
    } 
} 

Obviamente, el SM no tiene un acceso a FileOutputStream y no puede cambiar las variables internas en el método (como el nombre de o archivo) o de alguna manera afectar el orden de ejecución, excepto lanzando el SecurityException. Entiendo, que el acceso a los campos internos es una violación de los principios orientados a objetos, entiendo, que las variables locales son visibles y existen solo dentro del método, donde fueron declaradas.

Así que mi pregunta es: ¿hay alguna forma de permitir que Security Manager reemplace las llamadas al sistema de archivos? Si no, ¿hay algún otro enfoque que pueda usar para hacer esto?

Espero haber sido lo suficientemente claro.

Respuesta

6

El SecurityManager no puede hacer eso, solo puede decir sí o no.

puedo pensar en dos opciones:

  1. hacemos algo en el nivel de sistema operativo con el sistema de archivos. Hay cosas como chroot jails. Eso sería transparente para la aplicación, pero requiere trabajo fuera de Java.

  2. Proporcione una API a la aplicación que abre el FileOutputStream para ellos. La capa API puede decidir de dónde provienen los archivos y tiene privilegios (en términos de Security Manager) para abrir archivos desde cualquier lugar. Por supuesto, esto requiere que la aplicación de espacio aislado use su API en lugar de java.io.File directamente. Pero también es mucho más flexible, y en algún momento probablemente sea necesario que una aplicación conozca la zona de pruebas y use la API de sandbox, al igual que en Java WebStart for example.

+0

gracias por la respuesta. La primera opción que no pude aceptar, ya que no quiero restringirme a un sistema operativo, pero la segunda opción se ve bastante bien. Busqué un reemplazo de API y descubrí que la herramienta JMockit puede simular clases y hacer stubs. Así que, básicamente, investigaré y creo que esto es lo que necesito ahora. – Sevich

0

No creo que se pueda hacer. El administrador de seguridad está diseñado para denegar el acceso a operaciones específicas, no para redirigir IO o hacer otras cosas como esa.

, incluso si es posible a través de algunos hacks de reflexión seria, probablemente no será portátil entre diferentes proveedores de JVM e incluso diferentes sistemas operativos que ejecutan el mismo JVM. (Esto se debe a que necesitará manipular clases específicas del sistema operativo).

lo que quiere hacer debe intentarse en un nivel inferior, consulte chroot para Linux y otras técnicas de virtualización más pesadas.

5

Ahora que Java es de código abierto, se puede descargar el código fuente a FileOutputStream, modificar su código fuente para hacer cumplir lo que las limitaciones que desea, recompilar, añadirlo a un frasco, y anteponer dicho JAR a la ruta de clase del gestor de arranque de la JVM:

java -Xbootclasspath/p:myModifiedJavaClasses.jar sandbox.Main -run untrusted.Main 

la JVM utilizará ahora su implementación de java.io.FileOutputStream en lugar de la habitual. Enjuague y repita para todas las clases de JSE que necesiten una lógica de redirección de sandbox especial.

No es la solución más portátil o fácil de implementar, ya que requiere modificaciones "fuera de la máquina virtual" para iniciar los parámetros, pero en determinadas situaciones esta solución puede ser aceptable y efectiva.

Cuestiones relacionadas