安全图像下载

时间:2012-09-17 17:14:26

标签: php security file

我一直在研究安全上传图像,很明显,实际提供图像的大部分风险都在于可能危及服务器的流氓PHP文件。

许多人建议使用图像处理脚本,例如getimage.php?i = 575748,它将在数据库575748中查找并实际返回myphoto.jpg(不知道原始图像位置的用户)更安全。

能不能指出我应该在脚本中实现什么样的事情?我知道设置内容类型标题是必须的,但这足以阻止代码执行吗?

谢谢!

4 个答案:

答案 0 :(得分:0)

将上传文件夹放在根文件夹之外(即在/ www /或/ htdocs /或/ httpdocs /文件夹之外)。设置文件夹的权限,以便只有本地用户可以写入该文件夹。

至于数据库的想法,你肯定可以继续这样做,结合上面提到的想法,应该做一个相当安全的图像上传服务。

唯一的风险是当您没有为要上传的文件夹设置正确的权限时,这确实可能会危及服务器。

答案 1 :(得分:0)

啊,我明白了。如果您不希望将图像浮动到文件系统中,也可以将图像存储在数据库中。无论你喜欢哪种方式。让脚本提供图像而不是Apache的问题是图像必须加载到内存中。所以要为性能影响做好准备。

答案 2 :(得分:0)

  

很明显,实际提供图像的地方就在哪里   大多数风险是流氓PHP文件,可能会危及   服务器

只有在满足两个条件时才会发生这种情况:

  • 您允许上传非图片文件
  • 通过直接链接
  • 下载

阻止其中一个,危险消失。当然,关闭两者会更好。

数据库解决方案旨在破坏条件#2,但您也可以在上传图像时检查它确实是使用getImageSize()功能的图像。或尝试使用imageCreateFromJPEG()或其他适当的功能加载图像。

如果加载的对象不是图像,只显示“抱歉,图像已损坏”。这既可以保护您的用户免受上传损坏的图片,又可以防止有人上传流氓PHP文件(或者可能是受版权保护的视频或破解的可执行文件或......)。

更新:您还可以对现有的上传和下载工具进行模糊处理:

假设您当前上传了用户图片,请为其指定唯一ID,将其另存为./images/UNIQUEID.jpg,然后以用户身份http://www.yoursite.com/images/UNIQUEID.jpg作为网址投放。

  • 您应用.htaccess,以便./images/whatever的访问权限重定向到./images/index.php?ID=whatever
  • 您创建一个index.php脚本,其中包含“任意”,提取图像ID并输出图像。

所有旧的URL都将继续工作并且出现以直接加载图像,但他们实际做的是调用一个PHP脚本来检查图像并将其作为字节流发送,没有口译。

您需要将ETag设置为图片文件的ID,Last-Modifiedfile_mtime(),并将Content-Length设置为文件大小。此外,您可能需要检查传入标头If-Modified-SinceIf-None-Match:如果文件的日期对应于IMS或者IFN值对应于ID,则可以发送HTTP/304 Not Modified个答案而不是图像,节省了相当大的带宽。

答案 3 :(得分:0)

解决原始安全问题,在图像存储之前运行getimagesize() - 如果您从该功能中获取false,请将其丢弃。 (如果有人知道一个更好的解决方案来防止坏的“图像”通过,我全都耳朵!)

将图像存储在Web可访问目录之外的文件系统上。使用密钥表来物理位置是一个好主意。存储IMAGETYPE_XXX值(它是getimagesize()返回的数组的第二个索引)并打开它以使用imagejpeg()imagepng()等提供图像。当你这样做时,不要忘记设置你的内容类型标题。