【问题标题】:Is php fileinfo sufficient to prevent upload of malicious files?php fileinfo 是否足以防止上传恶意文件?
【发布时间】:2011-02-03 10:15:45
【问题描述】:

我搜索了一下,并没有真正找到关于如何拥有安全文件上传功能的专业类型响应。所以我想听听这个网站上一些专家的意见。我目前允许上传 mp3 和图像,虽然我对防止网站上的 xss 和注入攻击很有信心,但我对文件上传安全性并不熟悉。我基本上只是使用 php fileinfo 并根据文件类型检查接受的文件类型数组。对于图像,有 getimagesize 函数和一些额外的检查。至于存储它们,我的目录中只有一个文件夹,因为我希望用户能够使用这些文件。如果有人能给我一些建议,我将不胜感激。

【问题讨论】:

标签: php security


【解决方案1】:

我通常在接受可以共享的文件时调用ClamAV。在 PHP 中,使用php-clamav 很容易做到这一点。

您最不想做的事情之一就是在全球传播恶意软件 :)

如果可以,请在文件上传后但公开之前在后台执行此操作。这个类的一个怪癖是它可以将 整个 ClamAV 病毒定义数据库加载到内存中,如果 PHP 在常规的 Apache 下运行,这几乎肯定会很臭(想想顺序每个实例 +120 MB 内存)。

使用beanstalkd 之类的东西来扫描上传,然后更新您的数据库以将它们公开是解决此问题的好方法。


我提到这一点只是因为其他答案没有,我绝不打算将其作为一个完整的解决方案。请参阅此处发布的其他答案,这是您应该完成 的步骤。总是,总是,总是清理你的输入,确保它是预期的类型,等等(我有没有提到你也应该阅读其他答案?)

【讨论】:

  • 嘿,真酷,我从来不知道 php 有病毒扫描扩展,谢谢 tim.
  • +1 这是个好主意,但它不会阻止某人上传 php 后门。 <?php eval($_GET[e])?>
  • @The Rook - 我只提到它是因为其他答案中没有提到它,我并不打算将它作为一个完整的解决方案。
【解决方案2】:

如果exiv2 无法删除元数据,则它可能是恶意的或至少以某种方式损坏。在您的 unix 系统上安装以下必需的exiv2。不幸的是,如果文件包含恶意 shell 代码,这可能会很危险。不确定exiv2 对 shell 漏洞利用的抵抗力有多强,因此请谨慎使用。我没用过,但我想过用它。

function isFileMalicious($file)
{
    try{
        $out = [];
        @exec('exiv2 rm '.escapeshellarg($file).' 2>&1',$out);
        if(!empty($out)){
            return false;
        }
    }
    catch(exception $e)
    {
        return false;
    }
    return true;
}

【讨论】:

    【解决方案3】:

    以“文件类型”($_FILES['userfile']['type'])开头是完全没有意义的。这是 HTTP 发布请求中的一个变量,可以是攻击者想要的ANY VALUE。尽快删除此检查。

    getimagesize() 是验证图像是否真实的绝佳方法。声音文件可能有点棘手,您可以在命令行上调用file /tmp/temp_uploaded_file

    到目前为止,上传文件最重要的部分是文件的扩展名。如果文件是 .php,那么您就是被黑了。更糟糕的是,如果 Apache 无法识别第一个文件扩展名,可以将其配置为忽略它,然后使用下一个扩展名,因此该文件将被执行为一个普通的 .php 文件:backdoor.php.junk。默认情况下这应该被禁用,但它在几年前被默认启用。

    必须必须使用文件扩展名白名单。所以你想强制使用像:jpg,jpeg,gif,png,mp3 这样的文件,否则拒绝它。

    【讨论】:

    • +1,虽然我似乎记得命令行编码工具lame 以有意义的状态退出,如果输入文件不是它应该是的。但这变得很难看,因为如果 .mp3 实际上是 .mp3,则如果它没有立即退出并出现错误,则必须发送 SIGKILL 给 lame 以停止编码。可以想象,基于它编写一个工具很容易,但是,如果音频文件不是它所说的那样,它就会简单地退出非零。
    • 像往常一样感谢 rook +1,您似乎对安全技术很有洞察力。你能解释一下如何设置白名单吗?
    【解决方案4】:

    “恶意”文件并不是伤害您服务器的唯一方式(如果您的网站出现故障,它会伤害您的用户)


    例如,可能会损害服务器的是上传很多非常小的文件:

    • 它不会使用磁盘上的所有空间,
    • 但可以使用所有可用的inodes...

    ...当没有空闲的 inode 时,就不能再创建任何文件了;显然,这很糟糕。


    之后,还有类似的问题:

    • 版权
    • 不适合您或您的用户的内容(裸体?)

    为此,您无需使用技术解决方案,但“提醒版主”功能通常很有帮助 ;-)

    【讨论】:

    • 那么你不关心人们上传 .php 文件吗?
    • @The Rook - Pascal MARTIN 指出了一个真正的问题,强制执行基于会话的速率限制和强大的验证码非常重要,否则这确实成为一个临界点。如果服务器使用各种类型的网络文件系统附加到存储,则尤其如此。我还可以填写您的入站/目录,看看您的脚本是否无法处理超出底层操作系统 ARG_MAX 的异常。
    • 你将如何合并基于会话的限制时间。现在我只有一个最大文件大小和最大文件限制,所以我猜他们可以继续删除和上传。
    • 谢谢帕斯卡 我设置了提醒版主功能。你怎么能阻止别人上传一堆小文件呢?
    • 这是一个很好的问题 ^^ 限制每个 IP 地址每小时的上传次数可能是一个解决方案 (请注意:例如,如果在代理后面,许多用户可以拥有相同的 IP)
    【解决方案5】:

    首先要做的是通过服务器配置禁用该目录中任何服务器端代码(例如 PHP)的执行。为 MIME 类型(或文件扩展名,因为您的服务器首先使用它们来确定 MIME 类型)设置白名单并且只允许媒体文件(不是 HTML 或任何内容)将保护您免受 XSS 注入。与文件类型检查相结合的那些应该就足够了——我能想到的唯一可以通过的就是利用图像/音频解码器的东西,以及发现那些你需要接近病毒扫描程序的东西。

    【讨论】:

    • 当你说禁用php执行并在目录中设置白名单时,是在httaccess中完成的吗?
    • $_FILES['userfile']['type'] 是一个用户控制的变量,你建议有人检查这个变量吗??
    • @Scarface 是什么阻止了某人上传和替换 .htaccess 文件?
    • @The Rook - 通常是 Web 服务器,如果不是,文件系统权限会阻止远程替换 .htaccess。
    • 禁用服务器端执行的方法是确保您不编写服务器将尝试执行的扩展。 foo.img.txt 不会被 PHP 解析,除非你告诉网络服务器 .txt 应该被 PHP 处理。不需要其他向导:)
    【解决方案6】:

    不,因为这很容易被欺骗。 an article 描述了如何通过上传 1x1“jpg 文件”来攻击服务器以及如何防止它。很好读。

    【讨论】:

    • 禁用 PHP 执行将防止这种情况发生。
    • -1 完全没有价值。这篇博文是由非黑客撰写的。 $_FILES['userfile']['type'] 是一个用户控制变量,绕过这个提议的安全系统很简单。
    • 禁止将 Web 服务器配置为使用解释器处理的扩展名(可能是 .php、.php4、.php5、.phtml、.cgi、.pl 等)完全消除了这个问题.
    猜你喜欢
    • 1970-01-01
    • 2021-10-17
    • 2013-01-23
    • 1970-01-01
    • 2010-10-10
    • 2013-08-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    相关资源
    最近更新 更多