在php中安全执行bash脚本
我正在用php开发浏览器shell(它使用内置exec函数或perl或python中的cgi脚本),我希望允许来宾用户有限地访问shell。我有此功能来清理用户命令:在php中安全执行bash脚本,php,bash,shell,sandbox,Php,Bash,Shell,Sandbox,我正在用php开发浏览器shell(它使用内置exec函数或perl或python中的cgi脚本),我希望允许来宾用户有限地访问shell。我有此功能来清理用户命令: private function validate_command($command) { $commands = array('echo', 'cat', 'ls', 'find', 'cd', 'grep'); $cmd_re = "(" . implode("|", $commands) . ")";
private function validate_command($command) {
$commands = array('echo', 'cat', 'ls', 'find', 'cd', 'grep');
$cmd_re = "(" . implode("|", $commands) . ")";
$re = "/^\s*($cmd_re|xargs\s*$cmd_re)/";
$separators = "/(\||&&|\|\||;)/";
$parts = preg_split($separators, $command, null, PREG_SPLIT_DELIM_CAPTURE);
$result = array();
foreach ($parts as $part) {
if (preg_match($separators, $part)) {
$result[] = $part;
} else if (!preg_match($re, trim($part))) {
$last = array_pop($commands);
$message = "guest user can only execute: " .
implode(", ", $commands) . " and " . $last;
throw new Exception($message);
} else {
// escapeshellcmd is not use here because it escape quotes
// and * ? so you can't use find . -name "*.js"
$result[] = preg_replace('/(\\\\|`|\$\()/', "\\\\$1", $part);
}
}
return implode($result);
}
它适用于以下命令:
find projects/jcubic -name '*.js' | xargs grep jcubic
但不允许执行find/| xargs rm
或rm*
和转义$(
和`
这个函数安全吗?可以利用它执行不允许的命令吗?如果它不安全,我如何使它安全?困难吗
更新我在@jh1711评论后更新的功能:
private function validate_command($command) {
$commands = array('echo', 'cat', 'ls', 'find', 'cd', 'grep');
$cmd_re = "(" . implode("|", $commands) . ")";
$re = "/^\s*($cmd_re|xargs\s*$cmd_re)/";
$separators = "/(&&|\|\||\||;)/";
$parts = preg_split($separators, $command, null, PREG_SPLIT_DELIM_CAPTURE);
$result = array();
foreach ($parts as $part) {
if (!preg_match($re, trim($part)) && !preg_match($separators, $part)) {
$message = "guest user can only execute: " .
implode(", ", $commands) . " and xargs";
throw new Exception($message);
} else if (preg_match('/(>|`|\$\()/', $part)) {
throw new Exception("guest user can't use redirect to write to files" .
" or execute subshell");
} else {
$result[] = $part;
}
}
return implode($result);
}
还有什么我遗漏的吗?
validate_命令(“echo'@jh1711哦,我忘了重定向,谢谢。