我一直在研究安全上传图像,很明显,实际提供图像的大部分风险都在于可能危及服务器的流氓PHP文件。
许多人建议使用图像处理脚本,例如getimage.php?i = 575748,它将在数据库575748中查找并实际返回myphoto.jpg(不知道原始图像位置的用户)更安全。
能不能指出我应该在脚本中实现什么样的事情?我知道设置内容类型标题是必须的,但这足以阻止代码执行吗?
谢谢!
答案 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-Modified
至file_mtime()
,并将Content-Length
设置为文件大小。此外,您可能需要检查传入标头If-Modified-Since
和If-None-Match
:如果文件的日期对应于IMS或者IFN值对应于ID,则可以发送HTTP/304 Not Modified
个答案而不是图像,节省了相当大的带宽。
答案 3 :(得分:0)
解决原始安全问题,在图像存储之前运行getimagesize() - 如果您从该功能中获取false
,请将其丢弃。 (如果有人知道一个更好的解决方案来防止坏的“图像”通过,我全都耳朵!)
将图像存储在Web可访问目录之外的文件系统上。使用密钥表来物理位置是一个好主意。存储IMAGETYPE_XXX
值(它是getimagesize()
返回的数组的第二个索引)并打开它以使用imagejpeg(),imagepng()等提供图像。当你这样做时,不要忘记设置你的内容类型标题。