如何保护PHP图像上传脚本免受攻击


How can I protect a PHP image upload script from exploits?

我为当地一家非营利出版物创建了一个简单的页面,人们可以在这里上传照片。

我不擅长安全(出于无知,而不是故意疏忽),但我已经采取了以下步骤来保护这个页面:

•PHP脚本设置为只接受.jpg、.png和.tif文件进行上传
•保存表单内容的子文件夹的权限设置为700,保存上传照片的子文件夹权限设置为70
•根据文档,我的主机具有以下配置,以确保只有.php文件作为.php运行:

<FilesMatch '.php$>
    SetHandler php52-fcgi
</FilesMatch>

•我在相关(主要和保存的内容)文件夹中放了一个.htaccess文件:

RemoveHandler .php
RemoveHandler .inc
RemoveHandler .pl
RemoveHandler .cgi
RemoveHandler .py
RemoveHandler .fcgi

然而,一夜之间,有人发现了这个测试页面,并提交了一条看似完美的测试消息和小.jpg。这是一个私人测试页面,URL不直观,只有我和大约三个人知道;其他人都没有发送这个测试。

这显然让我担心有什么不正常的事情发生,我担心我对安全性了解不够,无法确保这个页面的安全。

有什么明显的东西我遗漏了吗?

在处理上传的数据时,您应该记住,在$_FILES数组中可以找到的所有数据都可能是伪造的。它通过HTTP传输,因此很容易将image.jpg mime提供给可执行文件。

1-检查真正的mime

PHP附带了一些功能来检查文件的真实mime。为此,您应该使用fileinfo

$finfo = new finfo(FILEINFO_MIME, "/usr/share/misc/magic");
$filename = "/var/tmp/afile.jpg";
echo $finfo->file($filename);

2-检查图像属性

你显然只想上传图像,所以收到的文件必须有宽度和高度:

使用getImageSize()获取有关图像的所有必需信息。如果返回false,则该文件可能不是图像,您可以将其删除。getImageSize也可以给你一个mime类型,但我不知道它是否可信。

2.5-重新处理图像

正如用户628405所建议的,用GD重新处理图像可能是更安全的做法

$img = imagecreatefrompng('vulnerable.png'); 
imagepng($img, 'safe.png');

显然,它必须根据图像类型进行调整。请参阅php文档中的所有imagecreatefrom*。

3-上传文件夹除了你已经做的以外:

请确保您的上传文件夹在网络上不可用。验证上传的文件,然后根据需要将其移动到其他文件夹并重命名文件。它将防止黑客执行恶意文件(如果url无法访问,则无法执行)。

进一步阅读:https://www.owasp.org/index.php/Unrestricted_File_Upload

不要依赖客户端的任何数据,包括内容类型!

不要将上传的文件保存在web根目录中。上传的文件应该只能通过脚本访问,以便更好地控制。

不要使用原始文件名和扩展名保存上传的文件!将此数据存储在数据库中,以便以后检索。

您可以检查文件的MIME类型,但不要担心,只要您的php处理程序只能执行.php文件,并且您注意不要将上传的.php文件保存在脚本中,就不会暴露任何安全漏洞。

这对php文件以及服务器上安装的任何其他服务器端脚本语言都有效。

一个更好的想法是将您接受的扩展保留在文件系统中

我会忽略传入文件的MIME类型和文件扩展名。这些可能是伪造的。

如果你正沿着这条路走下去,就把这些文件存储在一个目录中。

确保该目录只用于图像(音乐),然后通过查看文件格式获得一个脚本,在其上放置正确的扩展名。

还要确保该目录不能执行PHP(或其他任何内容)。

这会保证你的安全。