2008-11-27 13 views
21

? Quiero ejecutar un php-script desde php que usará diferentes constantes y diferentes versiones de clases que ya están definidas.¿Hay alguna forma de ejecutar el código php en un sandbox desde dentro de php

¿Existe una caja de arena php_module donde podría simplemente:

sandbox('script.php'); // run in a new php environment 

en lugar de

include('script.php'); // run in the same environment 

O es proc_open() la única opción?

PD: no se puede acceder al script a través de la web, por lo que fopen ('http://host/script.php') no es una opción.

Respuesta

10

Hay runkit, pero puede que le resulte más sencillo simplemente llamar al script a través de la línea de comandos (Use shell_exec), si no necesita ninguna interacción entre los procesos maestro e hijo.

+2

Acerca de runkit; no parece una caja de arena bien por descripción, o tal vez debería decir fácil. Puede prohibir las funciones, pero me gustaría prohibir TODAS menos las incluidas en una lista proporcionada. Si un usuario necesita una función, puedo evaluar su seguridad a mano, previa solicitud. Parece que la única forma es escribir un intérprete personalizado. Si la velocidad es un problema, puede hacer que convierta su AST en PHP u otro idioma, esto es lo que voy a hacer ahora, ya que no pude encontrar una solución lista. ¡Salud! Ps. Sí, vi que esta Q es vieja. Ds. – Frank

+0

Bueno ... Buena suerte para encontrar algo que pueda analizar PHP en AST;) Estoy de acuerdo con tu punto. – troelskn

+0

FYI runkit parece estar abandonado y es probable que desee compilar la versión CVS o una de las versiones parcheadas (http://github.com/tricky/runkit) si desea ejecutarla en una versión moderna de PHP – Eli

2

También, usted debe buscar en el backtick operator:

$sOutput = `php script_to_run.php`; 

Esto le permitirá inspeccionar la salida de la secuencia de comandos que está ejecutando. Sin embargo, tenga en cuenta que la secuencia de comandos se ejecutará con los privilegios que tiene, pero puede eludir esto mediante el uso de sudo en Linux.

Este enfoque también asume que tiene instalada la CLI de PHP, que no siempre es el caso.

1

Hay Runkit_Sandbox - es posible conseguir que funcione, es una extensión de PHP. Yo diría el camino a seguir.

Pero es posible que tengas que crear tu propio "espacio aislado", p. Ej. al restablecer el estado de variable global de los superglobales que usa.

class SandboxState 
{ 
    private $members = array('_GET', '_POST'); 
    private $store = array(); 
    public function save() { 
     foreach($members as $name) { 
      $this->store[$name] = $$name; 
      $$name = NULL; 
     } 
    } 
    public function restore() { 
     foreach($members as $name) { 
      $$name = $this->store[$name]; 
      $this->store[$name] = NULL; 
     } 

    } 
} 

Uso:

$state = new SanddboxState(); 
$state->save(); 

// compile your get/post request by setting the superglobals 
$_POST['submit'] = 'submit'; 
... 

// execute your script: 
$exec = function() { 
    include(func_get_arg(0))); 
}; 
$exec('script.php'); 

// check the outcome. 
... 

// restore your own global state: 
$state->restore(); 
0

sé que es tema no es 100% relacionado, pero que puede resultar útil para alguien n__n

function require_sandbox($__file,$__params=null,$__output=true) { 

    /* original from http://stackoverflow.com/a/3850454/209797 */ 

    if($__params and is_array($__params)) 
    extract($__params); 

    ob_start(); 
    $__returned=require $__file; 
    $__contents=ob_get_contents(); 
    ob_end_clean(); 

    if($__output) 
    echo $__contents; 
    else 
    return $__returned; 

}; 
+0

no funciona si el archivo $ __ intenta definir las constantes ya definidas. también puede romper las variables globales si $ __ file usa la palabra clave global o la matriz $ GLOBALS para hacer referencia a las variables en el ámbito global. – DrLightman

+0

He actualizado el código, pruébelo ahora: D, es útil para mí: D puede no ser perfecto, pero es útil para mí para requerir algunos archivos php que crean vars durante su ejecución que no quiero que estén en el alcance global: D – AgelessEssence

1

he desarrollado una clase de caja de arena de licencia BSD por esta misma propósito. Utiliza la biblioteca PHPParser para analizar el código de espacio aislado, compararlo con las listas blancas y listas negras configurables por el usuario, y presenta una amplia gama de opciones de configuración junto con una configuración predeterminada. Para sus necesidades, puede redefinir fácilmente las clases llamadas en su código de espacio aislado y encaminarlas a otras diferentes.

El proyecto también incluye un kit de herramientas de espacio aislado (¡solo en su máquina local!) Que se puede utilizar para experimentar con la configuración de la zona de pruebas, y una documentación manual y API completa.

https://github.com/fieryprophet/php-sandbox

+0

¿Hay alguna forma de usar su clase sin instalarla a través del compositor? No quiero instalarlo en el servidor en vivo. ¿Solo usando las clases simples? –

1

ejecución de la función dinámica plugin que permite que el archivo cargado y la función para ejecutar lo que quiera, sin embargo, sólo puede tomar y las variables que pueden ser json_encode 'ed volver.

function proxyExternalFunction($fileName, $functionName, $args, $setupStatements = '') { 
    $output = array(); 
    $command = $setupStatements.";include('".addslashes($fileName)."');echo json_encode(".$functionName."("; 
    foreach ($args as $arg) { 
    $command .= "json_decode('".json_encode($arg)."',true),"; 
    } 
    if (count($args) > 0) { 
    $command[strlen($command)-1] = ")";//end of $functionName 
    } 
    $command .= ");";//end of json_encode 
    $command = "php -r ".escapeshellarg($command); 

    exec($command, $output); 
    $output = json_decode($output,true); 
} 

el código externo es totalmente un recinto de seguridad y se puede aplicar cualquier restricción de permiso que desea haciendo sudo -u restricedUser php -r ....

Cuestiones relacionadas