【发布时间】:2013-09-21 12:43:12
【问题描述】:
我有一个用户可以上传文件的目录。
为了避免安全问题(例如有人上传恶意 php 脚本),我目前通过附加 .data 来更改文件的扩展名,但是在下载文件时,他们必须手动删除 .data。
另一种常见的解决方案是通过调用readfile() 将文件上传到Apache 不提供服务的目录和have a php script manage all downloads。
我想做的是简单地禁止在上传文件夹中执行任何脚本(php、perl、cgi 脚本,无论我将来可能安装什么)。 This SO answer 建议在该文件夹的 .htaccess 文件中添加以下行:
SetHandler default-handler
但是,在我的情况下,这没有任何效果(我放在该文件夹中的示例 php 脚本仍然执行)。我做错了什么?
Apache 配置
这台机器是一个运行Debian GNU/Linux 6.0.7 (squeeze) 的 VPS(虚拟专用服务器),据我所知(我记下了我在该服务器上运行的所有命令,所以我的“记忆”应该非常准确),我认为'不要更改 apache2 配置中的任何内容,除了运行 sudo apt-get install php5 并使用以下内容创建文件 /etc/apache2/sites-enabled/mysite.com:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName mysite.com
ServerAlias www.mysite.com
DocumentRoot /home/me/www/mysite.com/www/
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /home/me/www/mysite.com/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from All
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
【问题讨论】:
-
SetHandler default-handler可以很好地防止在子目录中执行 PHP 代码。确保将此作为第一行放在DOCUMENT_ROOTsubdir/.htaccess -
@anubhava 感谢您的回复。在
/etc/apache2/sites-enabled/mysite.com中,我的DocumentRoot设置为/home/me/www,而文件/home/me/www/subdir/.htaccess包含一行SetHandler default-handler,可由www-data读取(我使用sudo su www-data; whoami; cat /home/me/www/subdir/.htaccess进行检查,所以我怀疑这个问题与AllowOverride或类似的东西有关。 -
请确保 .htaccess 已启用,方法是在其中放入一些垃圾文本,看看它是否会产生 500 错误。
-
@anubhava 是的,当我将垃圾放入
.htaccess时,我得到一个Internal Server Error,感谢您的提示,我不知道如何检查它是否已启用。我尝试在/etc/apache2/sites-enabled/mysite.com中设置AllowOverride All,现在我得到一个奇怪的行为:访问http://mysite.com/subdir/时出现404 Not Found错误,但访问http://mysite.com/subdir/script.php仍然运行php 脚本。 -
我尝试了各种选项(直接在
/etc/apache2/sites-enabled/mysite.com中),发现禁用PHP 脚本的唯一方法是输入<Directory /home/me/www/subdir/>php_flag engine off</Directory>,甚至RemoveHandler .php .php3 .php4 .php5 .phtml都不起作用。这对我来说意味着 PHP 似乎会短路SetHandler指令。不幸的是,这意味着如果有一天我安装了另一个 CGI 引擎,例如perl,那么我也需要记住禁用它,因此使用php_flag engine off绝对不是禁用文件夹执行脚本的可靠方法。