Есть ли способ выполнить код php в песочнице изнутри php - PullRequest
22 голосов
/ 28 ноября 2008

Я хочу выполнить php-скрипт из php, который будет использовать разные константы и разные версии классов, которые уже определены.

Есть ли там песочница php_module, где я мог бы просто:

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

вместо

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

Или proc_open () единственный вариант?

PS: скрипт не доступен через Интернет, поэтому fopen ('http://host/script.php') не вариант.

Ответы [ 7 ]

10 голосов
/ 28 ноября 2008

Существует runkit , но вам может быть проще просто вызвать скрипт из командной строки (используйте shell_exec ), если вам не нужно взаимодействие между мастером и дочерние процессы.

5 голосов
/ 02 июля 2011

Это класс на GitHub, который может помочь на ранних стадиях, но выглядит многообещающе.

https://github.com/fregster/PHPSandbox

2 голосов
/ 28 ноября 2008

Кроме того, вы должны взглянуть на оператор backtick :

$sOutput = `php script_to_run.php`;

Это позволит вам проверить вывод скрипта, который вы запускаете. Тем не менее, обратите внимание, что скрипт будет запускаться с имеющимися у вас правами, но вы можете обойти это, используя sudo в Linux.

Этот подход также предполагает, что у вас установлен PHP CLI, что не всегда так.

1 голос
/ 10 сентября 2015

динамическое выполнение функции плагина, которая позволяет загруженному файлу и функции выполнять все, что она хочет, однако она может принимать и возвращать только переменные, которые могут быть 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);
}

внешний код полностью изолирован, и вы можете применить любые ограничения разрешений, которые вы хотите, выполнив sudo -u restricedUser php -r ....

1 голос
/ 04 марта 2013

Для этой цели я разработал класс песочницы, лицензированный BSD. Он использует библиотеку PHPParser для анализа изолированного кода, сравнения его с настраиваемыми пользователем белыми и черными списками, а также широким спектром опций конфигурации и нормальными настройками по умолчанию. Для ваших нужд вы можете легко переопределить классы, вызываемые в вашем изолированном программном коде, и перенаправить их на другие.

Проект также включает набор инструментов для песочницы (используется только на вашем локальном компьютере!), Который можно использовать для экспериментов с настройками песочницы, а также полное руководство и документацию по API.

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

1 голос
/ 17 апреля 2012

Есть Runkit_Sandbox - вы можете заставить его работать, это расширение PHP. Я бы сказал, куда идти.

Но вам может понадобиться создать свою «песочницу», например, сбрасывая состояние глобальной переменной используемых вами суперглобалистов.

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

    }
}

Использование:

$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 голосов
/ 12 января 2013

я знаю, что это не на 100% связано с темой, но может быть полезно для кого-то 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;

};
...