Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP中的安全用户图像上载功能_Php_Security_Image_File Upload_Upload - Fatal编程技术网

PHP中的安全用户图像上载功能

PHP中的安全用户图像上载功能,php,security,image,file-upload,upload,Php,Security,Image,File Upload,Upload,我正在为我的网站实现一个基于用户的图像上传工具。系统应允许任何用户仅上传JPEG和PNG文件。当然,我担心安全问题,因此我想知道有多少比我更聪明的人对以下允许上传的检查有何感受: 1) 首先列出PHP中允许的文件扩展名,以便仅允许PNG、PNG、jpg、jpg和JPEG。通过以下函数检索用户文件的扩展名: return end(explode(".", $filename)); 这将有助于禁止用户上传恶意内容,如.png.php。如果通过,请转至步骤2 2) 在TMP文件上运行php函数get

我正在为我的网站实现一个基于用户的图像上传工具。系统应允许任何用户仅上传JPEG和PNG文件。当然,我担心安全问题,因此我想知道有多少比我更聪明的人对以下允许上传的检查有何感受:

1) 首先列出PHP中允许的文件扩展名,以便仅允许PNG、PNG、jpg、jpg和JPEG。通过以下函数检索用户文件的扩展名:

return end(explode(".", $filename));
这将有助于禁止用户上传恶意内容,如.png.php。如果通过,请转至步骤2

2) 在TMP文件上运行php函数getimageize()。通过以下方式:

getimagesize($_FILES['userfile']['tmp_name']);
如果未返回false,则继续

3) 确保将.htaccess文件放置在uploads目录中,以便此目录中的任何文件都无法解析PHP文件:

php_admin_value engine Off
4) 将用户的文件重命名为预先确定的文件。即

$filename = 'some_pre_determined_unique_value' . $the_file_extension;
这也将有助于防止SQL注入,因为在所使用的任何查询中,文件名将是唯一由用户确定的变量

如果我执行上述操作,我仍然容易受到攻击吗?在接受一个文件之前,我希望1)只允许JPG和PNG,2)验证PHP是否说这是一个有效的图像,3)禁止图像所在的目录执行.PHP文件,4)将用户文件重命名为唯一的文件


谢谢,

关于文件名,随机名称绝对是一个好主意,可以消除很多麻烦

如果你想完全确定内容是干净的,考虑使用GD或IMAGEMGIK将输入的图像1:1复制到一个新的空的图像中。p> 这会略微降低图像质量,因为内容会被压缩两次,但会删除原始图像中存在的任何EXIF信息。用户通常甚至不知道JPG文件的元数据部分包含了多少信息!摄像机信息、位置、时间、使用的软件。。。对于承载图像的站点来说,为用户删除这些信息是一个很好的策略


此外,复制图像可能会消除大多数利用错误图像数据导致查看器软件溢出和注入恶意代码的漏洞。对于GD来说,这些被操纵的图像可能根本无法读取。

所有的检查似乎都很好,尤其是第3项。如果性能不是问题,或者您是在后台这样做的,您可以尝试使用GD访问图像,看看它是否确实是一个图像,而不仅仅是有人试图用一堆垃圾填满您的服务器。

关于您的数字2),不要只检查
FALSE
。getimagesize还将返回图像的mime类型。这是一种比查看客户端提供的mime类型更安全的检查正确图像类型的方法:

$info = getimagesize($_FILES['userfile']['tmp_name']);
if ($info === FALSE) {
    die("Couldn't read image");
}
if (($info[2] !== IMAGETYPE_PNG) && ($info[2] !== IMAGETYPE_JPEG)) {
    die("Not a JPEG or PNG");
}

关于第2条,我在php.net()上读到:

不要使用getimagesize()检查给定文件是否为有效图像。使用专门构建的解决方案,例如Fileinfo扩展


回答得很好。我只想补充一点,作为一种额外的防御,从一个废弃的域提供图像,而不是你设置cookie的域。这样,即使图像以某种方式具有可执行的客户端代码,浏览器的同源策略也将防止许多伤害。@sri好主意,我还没有想到这一点@SripathiKrishnan如何为图像设置丢弃域..任何参考..供您参考answer@sid-购买另一个域并提供该域中的图像。例如,google提供来自googleusercontent.com域的用户内容。@SripathiKrishnan谢谢。。我如何确保该域没有Cookie,上传照片时我必须在该域中保存图像?文件可能是有效的gif,同时包含php代码。因此getimagesize()不会提供太多真正的保护。@Andre:任何可以包含文本的东西都可以包含PHP代码。至少对于图像,除非Web服务器的配置非常糟糕,否则PHP不会被执行。我通常使用imagick将图像重新编码为bmp并返回到原始扩展名-这可以消除图像文件中的任何恶意代码。您可以使用图像文件上的strip_标记删除PHP标记吗?