2

问题很简单。如何使用 php 制作 100% 安全的照片上传脚本?是否有任何教程可以显示所有可能的安全漏洞?

不要让我看这个问题,因为他们只谈论大小。但我想确定的是,没有人可以上传 shell 和其他东西。因为它是一个需要 100% 安全的照片上传脚本的大型网站。

编辑:或者我应该允许会员将图片上传到像imageshack这样的容器并将他们的链接复制到我的网站?我想它是 100% 安全的,对吧?

4

3 回答 3

4

这真的很简单。通过已知安全的图像过滤器运行所有上传的图像。如果它以“不是图像错误”而反弹,则说明您有恶作剧。(一个简单的例子是恒等变换,或 JPEG 质量标准化技术。)重要的一点是实际使用过滤器的输出,而不是原始文件。

于 2010-06-24T21:51:31.803 回答
4

您需要考虑和注意的事项:

文件扩展名: Web 服务器使用文件扩展名来确定发送到客户端的 MIME 类型。您应该使用您允许的扩展白名单。在您的情况下,这将是图像扩展。

LFI:正如 Matchu 已经提到的,本地文件包含可能是一个问题。如果您的应用程序具有允许您包含任意文件的动态包含,例如。include($_GET['myfile']);它可能导致任意 PHP 执行。因此,您需要使用basename()来保护此类包含。这甚至可能发生在图像上,因为它们可以包含嵌入的评论。

MIME-Type-Detection:这个其实不是很为人所知,也没有太多关于它的信息。IE<8 有一个称为 MIME-Type-Detection 的功能,如果 Content-Type 与内容不匹配,它将尝试通过查看前 256 个字节来猜测类型。这意味着,如果您有一个名为 image.gif 的 PNG 文件,并且顶部的注释为<script>alert('hello');</script>,那么 IE<8 会认为它是 HTML 并执行 JavaScript,从而导致 XSS 攻击。

要防止图像出现此问题,您可以使用 Williham Totland 提到的方法。我建议使用getimagesize()来检测图像是否有效并确保扩展名与类型匹配。

$image_filename = 'uploaded_image.gif';
$image_extension = substr(strrchr($image_filename, '.'), 1);

$mime_mapping = array('png' => 'image/png', 'gif' => 'image/gif', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg');
$info = getimagesize($image_filename);

if (!$info) {
    exit('not an image');
}

if ($info['mime'] != $mime_mapping[$image_extension]) {
    exit('wrong extension given');
}

// all checks passed
// image can be saved now

这里有一篇关于这个问题的文章。

于 2010-06-24T23:17:51.873 回答
2

正如您所提到的,还有另一个问题可以解决这个问题。作者指出,只要他只接受正版图像文件并保持文件大小,他就应该是安全的,这是你唯一能做的事情。检查扩展名和 MIME 类型并拒绝任何与您想要的格式不匹配的内容。仍然有RFI(好吧,这里更像 LFI),但只要您不是在不执行完整性检查的情况下随意包含文件,您就可以开始了。

于 2010-06-24T21:53:09.277 回答