Question

I want to execute a php-script from php that will use different constants and different versions of classes that are already defined.

Is there a sandbox php_module where i could just:

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

instead of

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

Or is proc_open() the only option?

PS: The script isn't accessible through the web, so fopen('http://host/script.php') is not an option.

Was it helpful?

Solution

There is runkit, but you may find it simpler to just call the script over the command line (Use shell_exec), if you don't need any interaction between the master and child processes.

OTHER TIPS

The is a class on GitHub that may help, early stages but looks promising.

https://github.com/fregster/PHPSandbox

Also, you should look at the backtick operator:

$sOutput = `php script_to_run.php`;

This will allow you to inspect the output from the script you are running. However, note that the script will be run with the privileges you have, but you can circumvent this by using sudo on Linux.

This approach also assumes that you have the PHP CLI installed, which is not always the case.

There is Runkit_Sandbox - you might get it to work, it's a PHP extension. I'd say the way to go.

But you might need to create a "sandbox" your own, e.g. by resetting the global variable state of the superglobals you use.

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;
        }

    }
}

Usage:

$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();

I have developed a BSD-licensed sandbox class for this very purpose. It utilizes the PHPParser library to analyze the sandboxed code, check it against user-configurable whitelists and blacklists, and features a wide array of configuration options along with sane default settings. For your needs you can easily redefine classes called in your sandboxed code and route them to different ones.

The project also includes a sandbox toolkit (use only on your local machine!) that can be used to experiment with the sandbox settings, and a full manual and API documentation.

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

dynamic plugin function execution that allows the loaded file and function to execute anything it wants, however it can only take and return variables that can be json_encode'ed.

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);
}

the external code is totally sandboxed and you can apply any permission restrictions you want by doing sudo -u restricedUser php -r ....

i know its not 100% topic related, but maybe useful for somebody 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;

};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top