上传的安全威胁

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

比方说,我允许用户从他们的系统或networking上传图像到我的服务器。 现在要检查这些图像的大小,我必须将它们存储在我的/tmp文件夹中。 这不危险吗? 我怎样才能把风险降到最低?

也可以说我正在使用wget从用户上传的链接中下载图像。 我首先必须保存这些文件在我的服务器,以检查他们是否真的是图像。 另外如果恶作剧给了我一个URL,我最终下载整个网站的恶意软件?

首先,要意识到上传文件意味着用户正在以各种格式向您提供大量数据,并且用户可以完全控制这些数据。 这甚至是一个正常的表单文本字段的关注,file upload是相同的,还有更多。 第一条规则是:不要相信任何事情。

用户通过file upload得到的内容:

  • 文件数据
  • 一个文件名
  • 一个MIMEtypes

这些是file upload的三个主要组成部分,没有一个是可信的。

  1. 不要相信$_FILES['file']['type']的MIMEtypes。 这完全是任意的,用户提供的价值。

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

  3. 不要让任何人或任何东西任意访问文件。 例如,如果攻击者将malicious.phpfile upload到服务器,并将其存储在网站的webroot目录中,则用户可以简单地访问example.com/uploads/malicious.php来执行该文件并运行任意PHP代码在您的服务器上。

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

    • 只允许特定进程访问这些文件。 如果它应该是一个图像文件,只允许一个脚本读取图像,并调整它们直接访问文件。 如果此脚本在读取文件时遇到问题,则可能不是图像文件,请将其标记和/或丢弃。 其他文件types也一样。 如果文件应该是其他用户可以下载的,那么创build一个脚本来提供文件供下载,而不需要其他任何东西。

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


为了解决您的具体问题:

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

不。只要将数据存储在临时文件夹中的文件中,如果您没有对该数据进行任何操作,则不会有风险。 数据只是数据,不pipe其内容。 如果你试图执行这些数据,或者程序正在parsing数据,那么如果程序包含parsing错误,这些数据可能会被恶意数据欺骗,从而造成意想不到的事情。

当然,在磁盘上放置任何types的恶意数据比在任何地方没有恶意数据更具风险。 你永远不知道谁会来,并采取行动。 所以你应该validation上传的数据,如果没有通过validation就尽快丢弃。

如果一个恶作剧给了我一个url,我最终下载整个网站的恶意软件?

这取决于你下载的是什么。 一个URL最多会导致一个数据块。 如果您正在parsing这些数据,并且正在根据您的问题下载最初的blob的更多url的内容。 不要这样做。 但即使你做了,那么你会有一个临时目录充满了东西。 再一次,如果你没有对这些东西做任何危险的话,这并不危险。

1个简单的情况是:如果您使用上传界面,对允许上传的文件types没有任何限制,则攻击者可以上传带有恶意代码的PHP或.NET文件,这可能会导致服务器的妥协。

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

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

这里是其中的一些:

  • 当file upload到服务器时,PHP会将variables$ _FILES ['uploadedfile'] ['type']设置为客户端使用的Web浏览器提供的MIMEtypes。 但是,file upload表单validation不能仅依赖于此值。 恶意用户可以使用脚本或其他一些允许发送HTTP POST请求的自动应用程序轻松上传文件,从而允许他发送假的MIMEtypes。

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

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

有一些常见的规则来避免file upload的一般问题:

  • 存储不在您的网站根文件夹下的上传文件 – 因此用户将无法重写您的应用程序文件并直接访问上传的文件(例如,在/ var / www中,/ var / uploads中)。
  • 在数据库和物理文件中存储清理过的文件名称给出文件散列值的名称(这也解决了存储文件重复的问题 – 它们将具有相等的散列)。
  • 为了避免在/ var / uploads文件夹中存在太多文件的情况下文件系统的问题,考虑将文件存储在文件夹树中:

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

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

  • 如果你还没有完成它的话,安装nginx – 它像magic一样提供静态的,它的“X-Accel-Redirect”头允许你提供文件,