如何保护PHP映像上传脚本不受攻击?

问题描述:

我已经创建了(使用脚本,并从Stack和朋友的一些帮助;我对PHP知之甚少)本地非盈利性出版物的简单页面,人们可以在上面上传照片.

I've created (using a script and some help from Stack and some help from friends; I know very little about PHP) a simple page for a local non-profit publication where people can upload photos.

我对安全性不满意(基于无知而不是故意的疏忽),但我已采取以下步骤来保护此页面:

I'm not great with security (from a basis of ignorance, not deliberate negligence) but I've taken the following steps to protect this page:

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

• the PHP script is set to only accept .jpg, .png and .tif files for upload;
• the subfolder that it saves the form content to has permissions set at 700, and the subfolder it saves uploaded photos to has permissions set at 700;
• according to documentation, my host has the following configuration to ensure that only .php files run as .php:

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

•我已经将.htaccess文件放在相关的(主要和保存的内容)文件夹中:

• I’ve put an .htaccess file in the relevant (main and saved content) folders:

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

但是,一夜之间,有人找到了该测试页,并提交了看起来完全是良性的测试消息和小的.jpg.这是一个带有非直觉URL的私人测试页,只有我和另外三个人知道.其他人都没有发送此测试.

Overnight, however, somebody found this test page and submitted what seems to be a perfectly benign test message and small .jpg. This is a private test page with a non-intuitive URL that only I and about three other people know about; none of the others sent this test.

这显然让我担心发生了一些棘手的事情,而且我担心我对安全性了解不足以确保此页面是安全的.

This obviously has me worried that there's something hinky going on, and I'm worried that I don't know enough about security to make sure this page is safe.

有什么明显的我想念的东西吗?

Is there something obvious that I'm missing?

在处理上载内容时,请记住,在$ _FILES数组中可以找到的所有数据都是伪造的.它通过HTTP传输,因此可以很容易地将image/jpg哑剧赋予可执行文件为例.

When dealing with uploaded you should keep in mind that all the data you can find in the $_FILES array can be faked. It's traveling through HTTP so it's pretty easy to give the image/jpg mime to an executable file for exemple.

1-检查真实的哑剧

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

PHP come with some function to check the real mime of a file. For that you should use fileinfo

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

2-检查图像的属性

您显然只想上传图片,因此接收到的文件必须具有宽度和高度:

You apparently want to upload only image , so the received file must have a width and a height :

使用 getImageSize()获取有关图像的所有必需信息.如果返回false,则该文件可能不是图像,您可以将其删除. getImageSize还可以为您提供mime类型,但我不知道它是否可以信任.

Use getImageSize() to get all the required information about the image. If it return false , the file is probably not an image and you can delete it. getImageSize can also give you a mime type , but i don't know if it can be trusted.

2.5-重新处理图像

根据user628405的建议,用GD重新处理图像可能是更安全的操作.

As suggested by user628405 , reprocessing the image with GD is probably the more secure thing to do.

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

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

Obviously it has to be adapted according to the image type. See all the imagecreatefrom* in php documentation.

3-上传文件夹 除了您已经完成的工作之外:

3- Upload folder In addition of what you have already done :

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

Make sure your upload folder is not available from the web. Validate the uploaded file then move it to an other folder if needed and rename the file. It will prevent hacker from executing a malicious file (can't execute it if it can't be reached by an url).

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