Есть ли способ выполнить php-код в песочнице из php
Я хочу выполнить php-скрипт из php, который будет использовать разные константы и разные версии классов, которые уже определены.
Есть ли модуль php_module в песочнице, где я мог бы просто:
sandbox('script.php'); // run in a new php environment
Вместо
include('script.php'); // run in the same environment
Или proc_open() является единственным вариантом?
PS: Скрипт недоступен через Интернет, поэтому откройте ('http://host/script.php ') - это не вариант.
7 answers
Существует runkit, но вам может показаться проще просто вызвать скрипт через командную строку (используйте shell_exec), если вам не нужно никакого взаимодействия между основным и дочерними процессами.
Это класс на GitHub, который может помочь на ранних стадиях, но выглядит многообещающе.
Кроме того, вы должны посмотреть на оператор обратного отсчета :
$sOutput = `php script_to_run.php`;
Это позволит вам проверить выходные данные запущенного вами скрипта. Однако обратите внимание, что скрипт будет запущен с теми правами, которые у вас есть, но вы можете обойти это, используя sudo в Linux.
Этот подход также предполагает, что у вас установлен интерфейс командной строки PHP, что не всегда так.
Существует 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();
Я разработал класс песочницы с лицензией BSD именно для этой цели. Он использует библиотеку PHPParser для анализа изолированного кода, сверяет его с настраиваемыми пользователем белыми и черными списками и имеет широкий спектр параметров конфигурации наряду с разумными настройками по умолчанию. Для ваших нужд вы можете легко переопределить классы, вызываемые в вашем изолированном коде, и перенаправить их в другие классы.
Проект также включает набор инструментов для песочницы (используйте только на своем локальном компьютере!) тот может использоваться для экспериментов с настройками песочницы, а также с полным руководством и документацией по API.
Динамическое выполнение функции плагина, которое позволяет загруженному файлу и функции выполнять все, что он хочет, однако оно может принимать и возвращать только переменные, которые могут быть 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 ...
.
Я знаю, что это не на 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;
};