8

我注意到即使扩展名不是,也可以通过 PHP 运行文件.php,例如即使扩展名不是,文件test.xyz.php.whatever.zyx仍然可以使用 PHP 运行.php!它恰好包含.php.在文件名中,这足以让我的 Apache 运行 PHP 脚本。

我尝试(按照某人的建议)将其放入该.htaccess文件夹的文件中:

php_flag engine off

但它在我的机器上不起作用。

我现在知道的唯一解决方案是:

  • 重命名为不通过 PHP 运行的已知文件扩展名,例如.txt.
  • 从文件名中删除所有点,从而使其无扩展名。

但我仍然不确定这些解决方案如何在我的 Windows 服务器(使用 Apache)之外的其他服务器上工作。

是否有任何其他解决方案不需要以任何方式重命名文件名?

4

10 回答 10

5

To be completely secure, you'll need to do a couple of things:

Set your upload directory above your "public" folder, making it inaccessible from a browser. This setting is in php.ini (php config file). You'll need to restart Apache for this to take effect. On most Redhat / Fedora / CentOS web servers, this can be:

upload_tmp_dir = "/var/tmp/"

OR, on my local Windows 7 WAMP install, it is set to:

upload_tmp_dir = "c:/wamp/tmp"

Disable scripts from running on that directory (c:/wamp/tmp), in .htaccess:

RemoveHandler .php .phtml .php3
RemoveType .php .phtml .php3
php_flag engine off

In your PHP script, get the uploaded file, filter it based on mimetype (not filetype extension), change the filename, and put it into a secured publicly accessible folder. In more detail:

Preferably use an MVC framework, such as Zend Framework, which includes filetype filtering.

If you do all of that, you should be secure. Obviously you'll never be 100% safe, since there are countless obscure exploits targeting PHP, MySQL, the command line, etc, particularly on older systems. On larger company webservers (what I work on), they disable everything, and selectively enable only what is required for the project. With a system such as WAMP, they enable everything, to ease local development.

Good practice for working on a professional project is to get a cloud server account with Rackspace or Amazon, and learn how to configure php.ini, and httpd.conf settings, as well as PHP security best practices. In general, do not trust the users input, expect it to be corrupt / malicious / malformed, and in the end you'll be secure.

于 2013-01-08T15:02:10.330 回答
5

对于用户上传,我建议您在这种情况下在根路径上方的层中上传文件夹,只有您有权上传文件夹(直接寻址)并且攻击者无权访问此文件夹中的任何文件因此您禁用攻击者运行恶意文件的操作

于 2013-01-05T12:49:48.917 回答
3

首先,您需要了解这里发生了什么:

test.xyz.php.whatever.zyx

网络服务器上的这样一个文件本身不会做任何事情。只有添加的配置会告诉 Apache 在该文件上执行 PHP。

因此,如果您删除该添加的配置,Apache 将不会.php在其中找到 - 无论是在最后还是堆叠文件扩展的一部分。

检查您php在服务器配置中设置的处理程序。为上传目录删除它。这将不会解决您上传文件可能遇到的任何其他配置问题,但是 PHP 文件不再由 PHP 执行 - 如果我理解正确,这就是您想要的。

如果您在找出问题所在时遇到问题,您需要将 PHP 配置发布到您的httpd.conf文件中,并为您的系统发布相关的 Apache HTTPD 配置文件。

有人告诉你的指令.htaccess

php_flag engine off

仅当您将 PHP 作为 apache SAPI 模块运行时才有效。

于 2013-01-05T20:56:32.327 回答
1

就个人而言,这是我在任何情况下都不再将文件上传到 Web 服务器的主要原因。相反,我使用 S3 / Amazon SDK 将上传的临时文件直接移动到具有私有权限的 S3 上的存储桶(我使用 S3,任何其他 CDN 也可以正常工作)。如果该文件需要由 Web 客户端查看或查看,我使用与 SDK 集成的各种“getter”功能来获取文件并显示它。

每当您允许将任何类型的文件上传到 Web 服务器时,就会有很多不可控的变量开始发挥作用,管理权限、过滤甚至空间都可能很困难。使用 S3(或任何其他 CDN),这一切都非常易于管理,并且默认情况下所有文件都有效地与服务器隔离。

于 2013-01-09T17:56:12.433 回答
1

在 Apache 上,您可以禁用包含不受信任文件的目录的所有动态处理程序。

SetHandler default-handler
于 2013-02-01T12:30:31.860 回答
1

而不是php_flag engine off您可以使用单个目录的 .htaccess 文件删除 PHP 文件的处理程序。

在您禁用 PHP 的目录中,您的 .htaccess 应包括:

RemoveHandler .php .phtml .php3 .php4 .php5
RemoveType .php .phtml .php3 .php4 .php5

但是,您可能会摆脱以下情况,具体取决于AddHandler您在默认 Apache 配置中配置的类型,在 Windows 上应该在C:\Program Files\Apache<version>\conf\httpd.conf

RemoveHandler .php 
RemoveType .php 

您还需要确保在您的主 apache 配置文件中,包含 .htaccess 文件的目录包含在Directory已设置的语句中AllowOverride FileInfo。您可能希望考虑AllowOverride All是否将 .htaccess 文件用于其他目的 - 请参阅AllowOverride 的 Apache 文档以了解差异的解释。

于 2013-01-02T21:54:36.413 回答
0

以下.htaccess代码可以工作并拒绝访问包含“ php”的文件:

<FilesMatch "php">
    Deny from all
</FilesMatch>
于 2013-01-08T15:46:05.070 回答
0

一个简单的正则表达式就可以完成这项工作

<?php
$a = strtolower($_FILES["file"]["name"]);
$replace = array(".php", ".phtml", ".php3", ".php4", ".php5");
$_FILES["file"]["name"] = str_replace($replace, "", $a);
?>

这在任何服务器上都可以正常工作

于 2013-01-07T15:01:56.353 回答
0

这不是一个很好的答案,但希望在某些特殊情况下有用......

.htaccess你可以在这样的文件中使用 mod_rewrite :

RewriteRule ^(.+).xyz.php.whatever.zyx$ index.php?openfile=$1 [NC,L]

在你的index.php文件里面:

$file = secure_this_string($_GET['openfile']);
include($file.'.xyz.php.whatever.zyx');  # or some other files

出于安全原因,请记住查看此答案StackOverFlow

并在test.xyz.php.whatever.zyx文件中:

<?php echo 'hello';

现在如果客户端请求 /test.xyz.php.whatever.zyx 文件,输出应该是 'hello'

于 2013-01-02T22:10:21.980 回答
0

我可以很容易地在我们的服务器上重现您的问题。有一种方法可以解决这个问题,您需要编辑 /etc/mime.types 并注释掉行

#application/x-httpd-php                                phtml pht php
#application/x-httpd-php-source                 phps
#application/x-httpd-php3                       php3
#application/x-httpd-php3-preprocessed          php3p
#application/x-httpd-php4                       php4
#application/x-httpd-php5                       php5

这些行会导致处理任何名称为 .php 的内容。注释掉 mime.types 中的条目后,/etc/apache2/mods-enabled/php5.conf 中的 mod_php 配置具有此条目,它仅正确处理.php 结尾的文件

<FilesMatch "\.ph(p3?|tml)$">
    SetHandler application/x-httpd-php
</FilesMatch>

真正可怕的是这是一个默认配置(在我们的例子中是 Ubuntu 10.04)。


编辑

在 Windows 上,mime.types 文件应该在 apache_home/conf/mime.types

于 2013-01-08T02:57:30.073 回答