我一直在研究安全上传图像,很明显,实际上为图像提供服务是恶意PHP文件的最大风险所在,这可能会危及服务器。
许多人建议,拥有在数据库575748中查找并实际返回myphoto.jpg (无需用户知道原始图像的位置)的图像处理脚本(例如getimage.php?i=575748 )要安全得多。
我应该在脚本中实现什么样的东西,有没有人能给我指出正确的方向?我知道设置内容类型标头是必须的,但这足以停止代码执行吗?
谢谢!
发布于 2012-09-18 01:37:17
很明显,实际提供图像是恶意
文件的最大风险所在,这可能会危及服务器
只有在满足两个条件时才会发生这种情况:
上传非图像
阻挠其中一个,危险就消失了。当然,两者都关闭会更好。
数据库解决方案旨在破坏条件#2,但您也可以在上传图像时使用getImageSize()函数检查它是否确实是图像。或者试图用imageCreateFromJPEG()或其他适当的函数加载图像。
如果加载的对象不是图像,只需显示“对不起,图像已损坏”。这既可以保护用户不上传损坏的图像,也可以防止有人上传恶意PHP文件(或者可能是受版权保护的视频或被破解的可执行文件等)。
更新:您还可以对现有的上传和下载工具进行模糊处理:
假设您当前上传了用户图像,为其分配了一个惟一的ID,将其另存为./images/UNIQUEID.jpg,并将其作为http://www.yoursite.com/images/UNIQUEID.jpg提供给用户。
./images/index.php?ID=whatever
.htaccess,以便将对./images/whatever的访问重定向到创建一个index.php脚本,该脚本采用“./images/index.php?ID=whatever所有旧的URL将继续工作,看起来像是直接加载图像,但它们实际所做的是调用一个PHP脚本来检查图像,并将其作为字节流发送,而不需要解释。
您需要将ETag设置为图像文件的ID,将Last-Modified设置为file_mtime(),将Content-Length设置为文件大小。此外,您可能希望检查传入的头文件If-Modified-Since和If-None-Match:如果文件的日期对应于IMS,或者INFN值对应于ID,则可以发送HTTP/304 Not Modified应答而不是图像,从而节省大量带宽。
发布于 2012-09-18 01:29:46
首先,将上传文件夹放在根文件夹之外(即/www/、/htdocs/或/httpdocs/文件夹之外)。设置对该文件夹的权限,以便只有本地用户可以对其进行写入。
至于数据库的想法,你绝对可以结合上面提到的想法去做,这应该是一个相当安全的图像上传服务。
唯一的风险是当你没有在你要上传到的文件夹上设置正确的权限,这确实可能会危及服务器。
发布于 2012-09-18 01:30:34
啊我明白了。如果不想让图像在文件系统中浮动,也可以将图像存储在数据库中。无论你喜欢哪种方式。让脚本而不是Apache服务于图像的问题是,图像必须加载到内存中。因此,要为性能影响做好准备。
https://stackoverflow.com/questions/12464119
复制相似问题