如何防御与图像远程文件包含,例如使用 .gif 文件 (Apache/PHP) 的 RFI?

信息安全 应用安全 Web应用程序 php 上传文件
2021-08-22 04:25:12

为了防御攻击者试图滥用图像文件的远程文件包含,我通常建议不要使用include将图像文件包含到 PHP 代码中。

但有时,可能根本不可能避免 image include(无论出于何种原因,都无所谓)。

在这种情况下,我通常会在上传过程中的某处提取图像并将它们转换为另一种图像格式(有时与有损压缩相结合),以希望破坏原始图像中可能包含的任何恶意代码。

这行得通,但我对它不太满意。主要是因为这种处理会产生额外的服务器负载,并且有时可能会发生可能的图像质量下降。

有什么更聪明的方法或最佳实践吗?

编辑

澄清一下:我说的是攻击者将 PHP 代码注入图像文件以在上传图像后在服务器端执行注入代码的情况。例如,论坛允许用户上传头像(小图像文件)以进行个性化。

4个回答

您的 PHP 代码不应该评估数据文件。它可能会打印出图像文件的内容,但是include()对图像文件进行编码是对代码的疯狂使用。我强烈假设您正在做的是使用 PHP 代码来提供图像,并且因为 PHP 不会评估不在"<? ?>"标签之间的任何内容,所以这在大多数情况下都有效。这绝对是错误的做法。

您可能正在寻找该readfile()功能。

除此之外,不要编写包含外部输入的语句。

使用 GD 函数进行转换是解决问题的好方法,但正如您所注意到的那样会增加开销。另外你为什么使用包含?

我猜你已经做了所有常见的缓解措施:

  • 只允许某些扩展并检查它们
  • 使用随机文件名
  • 使用 getimagesize()
  • 检查内容类型

您可以尝试的其他事情

  • 禁止执行图片上传目录中的php文件
  • 使用单独的域上传图像或将它们存储在 webroot 之外

我很难想到使用include(), 包含和评估/执行图像文件的场景,作为另一个 PHP 文件的一部分是一个有效的场景,你什么时候需要这个?
你能详细说明一下情节吗?

如果您需要include()一个文件,它将被评估。由于许多图像格式允许添加注释,因此该文件可能包含有效的 PHP 命令。所以防御要么是复制图像的内容/数据,并将其存储在一个新文件中,要么是删除评论。

有损压缩很可能是一种矫枉过正(尽管我想应该可以伪造一个包含操作码的图像,该操作码将在包含它时作为有效的 PHP 被解释为有效的图像,同时又是一个有效的图像;我不知道它是否将在无损图像副本完好无损的情况下存活)。


如果您谈论的是上传的图像,其中包含由网络服务器在提供图像时执行的 PHP 代码,则防御要容易得多:

  • 不允许将 .php 以外的文件扩展名作为 PHP 插入。
    如果您需要动态 PHP 创建.png的文件,请重命名它们.png.php并使用 URL 重写来隐藏.php客户端。
  • 将上传的图像(或任何文件)移动到配置为被 PHP 忽略的目录。
  • 切勿以原始名称存储上传的文件。

Suhosin Hardened-PHP模块对远程文件包含(RFI)/本地文件包含(LFI)攻击具有一定的保护作用。PHP 的open_basedir配置可用于防止 LFI 攻击。例如强制 PHP 从只读目录中包含。设置 可以完全防止 RFI allow_url_include=Off,这已经是多年前的默认设置了。

强化配置是一种很好的纵深防御方法。但它不能替代测试您的软件和修补已知漏洞。w3af 项目是开源的,可用于测试 LFI/RFI 漏洞。 Sitewatch是我用来确保我的 Web 应用程序安全的工具。