【问题标题】:Risks of a php image upload form? [duplicate]php 图片上传表单的风险? [复制]
【发布时间】:2013-03-08 01:53:24
【问题描述】:

所以我有一个客户想要一个摄影网站,用户可以在其中上传照片以响应摄影比赛。虽然从技术上讲这不是问题,但我想知道与允许任何用户能够将任何图像上传到我的服务器相关的风险。我感觉风险很高......

我正在考虑使用类似 http://www.w3schools.com/php/php_file_upload.asp

的东西

如果我确实让匿名用户上传文件,我如何保护图片(以及可能具有破坏性的文件)将上传到的目录?

【问题讨论】:

  • 永远不要使用来自w3fools 的任何东西。他们的代码很垃圾而且非常不安全。它们以任何方式/形状/形式都不是有用的资源。他们基本上只是一个具有良好 SEO 的垃圾邮件网站。
  • @MarcB 注意。但是,在复杂性方面,我要写的内容与该脚本相似。这不会是一个copypasta的工作。

标签: php apache


【解决方案1】:

如果您想确保图像是真实图像,您可以使用 gd http://www.php.net/gd 加载

如果 gd 资源创建正确则图像是真实图像

首先使用以下方法检测 mime:

getimagesize($filename);

那么,例如,如果它是一个 jpeg 加载到 gd 中:

$gdresource = imagecreatefromjpeg($filename);

如果$gdresource 有效/创建时没有警告,则图像有效且未损坏...getimagesize()(可能)不足以检测损坏的图像

另外,另一个重要说明...不要依赖$_FILES['blabla']['name'],因为它可能包含无效的 utf-8 序列(例如,假设您使用的是 utf-8)并且它可能是一种潜在的攻击机制,作为任何用户输入

因此您还需要对其进行验证/清理

$originalFileName = $_FILES['blabla']['name'];
$safeOriginalFileName = iconv('UTF-8', 'UTF-8//IGNORE', $originalFileName);
// more additional checks here. for example filename is empty ""
move_uploaded_file(...., $safeOriginalFileName);

另外,请记住$_FILES['blabla']['name'] 包含文件扩展名,这可能不正确。因此您需要将其剥离并使用实际正确的扩展名(您之前使用 getimagesize() + imagecreatefrom*() 解决的扩展名)

 $safeOriginalFileName = basename( $safeOriginalFileName ); // removes the extension
 $safeOriginalFileName = $safeOriginalFileName . ".jpg"; // correct extension

希望这会有所帮助:)


也正如 DaveRandom 指出的那样,不要也依赖 $_FILES['blabla']['type'],而是按照我的建议使用 getimagesize() + imagecreatefrom*()

【讨论】:

    【解决方案2】:

    上传的文件存储在一个临时位置,这个位置可以在$_FILES变量中找到。

    当您的脚本接受上传的文件时,您可以使用move_uploaded_file() 将其移动到您选择的位置。

    因此,即使用户是匿名的,您也可以控制如何处理上传以及是否接受它们(例如基于内容、大小等)。

    此外,(匿名)用户提供文件和随附的详细信息。因此,如果您盲目地使用这些详细信息,那么您很容易受到攻击(有不良意图的用户可能会提供错误的详细信息,以使其合法化)。因此,如果您需要这些详细信息,请自行收集(而不是使用 $_FILES)!

    欲了解更多信息,请参阅PHP documentation

    【讨论】:

      【解决方案3】:

      您将需要进行一些研究,但主要是以下主要提示:

      • 您可以拥有的基本安全措施是实际检查图像的 MIME 类型和扩展名。虽然这当然很容易伪造。

      • 使用像readfile()fopen()file_get_contents()这样的二进制安全函数,我不记得具体是哪些,但是有一些php函数在处理文件时存在安全问题,研究哪些是和避开他们。

      • 有一些函数使用preg_match() 和类似的函数来检查您正在阅读的文件中是否有类似于脚本的内容。使用它们来确保没有隐藏的脚本。这会稍微减慢这个过程,因为preg_match() 读取大文件可能会耗费资源,但应该不会很明显

      • 您还可以像电子邮件服务一样触发防病毒软件在上传的文件上运行。

      据我所知,具有潜在破坏性的图像通常会包含脚本语言,例如用于尝试 XSS 攻击的 php 代码或 javascript,存在很多危险,所以我猜你不能保证 100% 安全文件,但请定期查看以了解所有新的危险和避免它们的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-03
        • 2014-05-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多