上传时的安全威胁

时间:2012-06-16 06:26:19

标签: php upload

我允许用户将文件上传到我的服务器。我面临哪些可能的安全威胁?如何消除它们?

假设我允许用户通过系统或网络将图像上传到我的服务器。现在要检查这些图像的大小,我必须将它们存储在我的/tmp文件夹中。风险不大吗?我该如何将风险降至最低?

另请假设我使用wget从用户在表单中上传的链接下载图片。我首先要将这些文件保存在我的服务器中,以检查它们是否真的是图像。如果恶作剧者给我一个URL并且我最终下载了一个充满恶意软件的整个网站呢?

4 个答案:

答案 0 :(得分:32)

首先,要意识到上传文件意味着用户正在以各种格式为您提供很多数据,并且用户可以完全控制该数据。这甚至是普通表单文本字段的问题,文件上传是相同的,还有更多。第一条规则是:不要相信任何一条规则。

您通过文件上传从用户那里获得的信息:

  • 文件数据
  • 文件名
  • MIME类型

这些是文件上传的三个主要组成部分,并且都不可信任。

  1. 不信任$_FILES['file']['type']中的MIME类型。这是一个完全随意的用户提供的价值。

  2. 不要将文件名用于任何重要的事情。这是一个完全随意的用户提供的价值。您不能信任文件扩展名或一般名称。不要使用'dir/' . $_FILES['file']['name']之类的文件将文件保存到服务器的硬盘上。如果名称为'../../../passwd',则表示您正在覆盖其他目录中的文件。始终自己生成一个随机名称以将文件另存为。如果需要,可以将原始文件名作为元数据存储在数据库中。

  3. 绝不让任何人或任何人随意访问该文件。例如,如果攻击者将malicious.php文件上传到您的服务器并将其存储在您网站的webroot目录中,则用户只需转到example.com/uploads/malicious.php即可执行该文件并运行任意PHP服务器上的代码。

    • 永远不要将任意上传的文件存储在任何地方,始终将它们存储在只有您的应用程序可以访问它们的地方。

    • 仅允许特定进程访问文件。如果它应该是图像文件,则只允许读取图像的脚本并调整它们的大小以直接访问文件。如果此脚本在读取文件时遇到问题,则可能不是图像文件,标记它和/或丢弃它。其他文件类型也是如此。如果该文件应该可供其他用户下载,请创建一个脚本,为该文件提供下载,并且不对其进行任何其他操作。

    • 如果您不知道要处理的文件类型,请自行检测文件的MIME类型和/或尝试让特定进程打开文件(例如,让图像调整大小的过程尝试调整所谓的图像大小)。在这里也要小心,如果该过程中存在漏洞,则恶意制作的文件可能会利用它,这可能导致安全漏洞(此类攻击最常见的例子是Adobe的PDF阅读器)。


  4. 解决您的具体问题:

      

    [T] o检查这些图像的大小我必须将它们存储在我的/ tmp文件夹中。风险不大吗?

    没有。如果您没有对该数据执行任何操作,仅将数据存储在临时文件夹中的文件中并不存在风险。数据只是数据,无论其内容如何。如果你正在尝试执行数据,或者程序正在解析数据,如果程序包含解析缺陷,那么可能会被恶意数据欺骗做出意外的事情,这样做是有风险的。

    当然,在磁盘上放置任何类型的恶意数据比在任何地方都没有恶意数据风险更大。你永远不会知道谁会来,并用它做点什么。因此,如果未通过验证,您应该验证所有上传的数据并尽快将其丢弃。

      

    如果一个恶作剧者给了我一个网址并且我最终下载了一个充满恶意软件的整个网站怎么办?

    取决于你下载的内容。一个URL最多会产生一个数据块。如果您正在解析该数据,并且正在根据您的问题初始blob下载更多URL的内容。不要这样做。但即使你这样做了,那么你还有一个充满东西的临时目录。再说一次,如果你没有做任何危险的事情,这并不危险。

答案 1 :(得分:5)

1个简单的场景将是: 如果您使用上传界面,其中对上传文件的类型没有限制,则攻击者可以上传带有恶意代码的PHP或.NET文件,从而导致服务器泄露。

参阅: http://www.acunetix.com/websitesecurity/upload-forms-threat.htm 上面的链接讨论了常见问题

还请参考: http://php.net/manual/en/features.file-upload.php

答案 2 :(得分:3)

以下是其中一些:

  • 当文件上传到服务器时,PHP会将变量$ _FILES ['uploadedfile'] ['type']设置为客户端使用的Web浏览器提供的mime类型。但是,文件上载表单验证不能仅依赖于此值。恶意用户可以使用脚本或其他允许发送HTTP POST请求的自动应用程序轻松上传文件,这样就可以发送假的mime类型。

  • 编译包含攻击者可以使用的所有可能扩展名的列表几乎是不可能的。例如。如果代码在托管环境中运行,通常这样的环境允许使用大量脚本语言,例如Perl,Python,Ruby等,并且列表可以是无穷无尽的。

      

    恶意用户可以通过上传名为“.htaccess”的文件轻松绕过此类检查,该文件包含一行代码如下:AddType application/x-httpd-php .jpg

答案 3 :(得分:3)

有一些通用规则可以避免文件上传的一般问题:

  • 将上传的文件存储在您的网站根文件夹下 - 这样用户就无法重写您的应用程序文件并直接访问上传的文件(例如 / var / uploads 当您的应用位于 / var / www )时。
  • 在数据库和物理文件中存储已清理的文件名称会给出文件哈希值的名称(这也解决了存储文件重复的问题 - 它们将具有相同的哈希值)。
  • 为避免文件系统出现问题,以防/ var / uploads文件夹中的文件太多,请考虑将文件存储在文件夹树中:

    file hash = 234wffqwdedqwdcs - >将其存储在/var/uploads/23/234wffqwdedqwdcs

    通用规则: /var/uploads/<first 2 hash letters>/<hash>

  • 安装 nginx 如果你还没有完成它 - 它提供静态魔术,它的'X-Accel-Redirect'标题将允许你提供自定义脚本首先检查权限的文件