我在最新的 Debian 上安装了 Apache 2.4 和 PHP 5.5.14。根据 Apache 安全提示和技巧,我将 httpd.conf 设置为:
<Directory />
AllowOverride none
Require all denied
</Directory>
<Directory "/var/www">
Options FollowSymLinks
AllowOverride none
Require all granted
</Directory>
我重新启动 Apache 服务器并运行此 PHP 代码:
<?php
$filename = "/etc/passwd";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
echo($contents);
?>
代码获取了整个 /etc/passwd 文件,我认为这是一个巨大的安全问题。现在,我已经尝试通过阅读手册解决这个问题几天了,但还没有成功。我希望得到正确的指导,谢谢。
答案1
但请注意,这open_basedir
只会限制 PHP 函数等的目录访问,而不会限制通过 PHP 执行的外部程序。例如:
<?php
$file = shell_exec('cat /etc/passwd');
echo $file;
/etc/passwd
将毫无问题地输出文件的内容,因为文件系统访问不是由 PHP 本身调用的,而是由cat
程序调用的。默认情况下cat
由用户运行www-data
(在 Debian 上),因此这里只适用常规的操作系统文件访问权限(即文件所有者、组和世界的访问)。
为了防止这种情况,您可以
- 禁用通过以下方式执行 shell 命令的功能,
exec()
例如passthru()
system()
shell_exec()
disable_functions
在你的php.ini
, - 更改文件的权限,这样运行 Web 服务器(或 PHP)的用户就没有权限读取文件或
- 将 Apache 或 PHP 放入 chroot jail 中(尽管我自己从未尝试过)。
根据您的 Apache/PHP 配置和需求,这disable_functions
可能是最容易设置的,但它可能会破坏 ImageMagick 之类的东西,这些东西经常使用exec()
(例如exec('/usr/bin/convert ...')
ImageMagick)。
我在 Debian Squeeze 上测试了这一点,Apache 和 PHP 是来自存储库的 mod_php,Ubuntu 14.04 上通过 php-fpm 运行 Apache 和 PHP,也是使用存储库中的软件包。这可能也适用于 Windows 上的 PHP,但我从未尝试过……尽管cat /etc/passwd
惯于工作 :-)
答案2
您可以使用open_basedir
在中定义的参数php.ini。此参数将阻止 PHP 脚本访问文件(例如打开()或者包括()) 在 open_basedir 中指定的目录之外。请参阅这一页用于文档。