【问题标题】:Can something "bad" happen via img src?可以通过 img src 发生“坏”的事情吗?
【发布时间】:2011-03-08 01:22:23
【问题描述】:

我知道,我知道,标题很糟糕,但我会试着解释一下我的意思。所以,我要求我的成员展示他们的照片。他们将其上传到某个地方,然后将他们照片的 URL 粘贴到输入中,然后我将其保存到我的数据库(MYSQL)中。然后,在他们的个人资料中可以看到这张照片。我从数据库中获取 URL 并执行类似操作:<img src="<?=$photo;?>" height="123px" width="123px">"> 其中$photo 是从 MYSQL 获取的 URL。它完全安全吗?有人可以上传例如 .php 文件并损害我的网站吗?我需要检查 URL 的结尾是 .gif、.png、.jpg 吗?
谢谢。

编辑: 是的,我当然会保护我的网站免受 SQL 注入和 XSS 攻击。但是有什么方法可以以其他方式损害我的网站吗?

【问题讨论】:

  • 在插入数据库之前,使用 imagemagik 验证照片是真实图像,而不是其他图像,应该没问题。
  • “它完全安全吗?”这是完全不安全的 :) 如果不是其他的,这里可能会发生各种 xss 攻击。 @Byron 这是个好方法,假设 imagemagick 是安全的,但如果它不是银行网站,那么这不是真正的威胁。
  • <img src="<?=htmlspecialchars($photo);?>" height="123px" width="123px">">。但是,这并不能防止 XSRF(例如,用户输入 /logout.php 作为图像 URI 可能是一件坏事)
  • @Byron:即使图像在脚本检查时有效,但稍后在图像主机上用恶意内容替换照片也是微不足道的。
  • @Marc,正确。我以为他正在将图像源下载到数据库中并提供字节。

标签: php mysql html


【解决方案1】:

严格来说 - 是的。我可以在您的网站上发布一张由我的服务器托管的图片。

<img alt="Kobi's Photo" src="http://example.com/photo.jpg" />

看似天真无邪,但实际上,您网站上的每一位访问者,只要观看我的图像,都可以被跟踪和记录。每个访问者都会在我的服务器中获得一个会话,甚至可以得到一个 cookie(不是有趣的那种)。更糟糕的是,我可以跟踪显示我照片的访问者的每一次页面浏览 - 浏览器通过引用标题发送显示照片的每个 URL。
通过让人们托管自己的照片,您就泄露了访问者的一些隐私。

【讨论】:

    【解决方案2】:

    如果您允许用户将任何 URL 指定为个人资料图片,攻击者可以利用它来促进针对较小网站的拒绝服务攻击。它对目标网站的影响相当于被点了点。例如,攻击者可以将他/她的个人资料图片 URL 更改为目标网站上托管的大型资源。每次您网站的访问者看到攻击者的个人资料时,目标网站都会浪费带宽为访问者提供资源。

    对此的解决方案是只允许链接到图片托管网站的个人资料图片 URL。

    【讨论】:

      【解决方案3】:

      要做的几件事是验证它是可接受格式(通常是 jpg、png 和 gif)的真实图像,并清理和更改文件名。

      您可以使用PHP getimagesize function 来检查它是否为有效图片,以及哪种格式。上传文件时,您会收到所谓的 MIME 类型,但这对验证无用。因此,以下应该可以工作,因为 getimagesize 函数还可以验证图像并返回 exif 类型。

      $image_info=getimagesize($tempname);
      
      $allowed_types=array(IMAGETYPE_PNG,IMAGETYPE_JPEG,IMAGETYPE_GIF);//these are actually the integers 1, 2 and 3
      
      if(in_array($image_info[2],$allowed_types)){
         //image is a valid image. You can also check the height and width.
         }
      

      在您的上传处理中,为您的文件指定一个您选择的新的唯一名称是个好主意,这样您就不必担心他们会对文件名做任何奇怪的事情。

      编辑: 我注意到您指的是用户提供图像的 URL。

      我给出的答案与接受、存储和显示用户上传到您的服务器的图像有关。

      同样的原则也适用于显示图像的 URL。您可以通过 cURL 或 fopen 获取图像,将其保存到临时文件,然后检查它是否真的是如上所述的图像。这也可以捕获链接到不存在或无效图像的用户,因此您可以警告他们。此外,强制执行文件大小/尺寸限制 - 您不希望有人在其个人资料中链接到 5 GB 图片(尽管这将是他们自己的带宽问题),因为这可能会给您的其他用户带来不便。不过,用户以后总是可以将文件更改为其他内容。您可以每 x 小时检查一次,并警告正在做可疑事情的人,但这对您来说似乎很费力。

      您还可以强制执行文件名规则,例如在文件名中不要使用 unicode,并且名称不得包含 ''""# -,这些字符很少出现在合法图像 URL 中。

      【讨论】:

        【解决方案4】:

        您可以使用正则表达式来过滤 PHP 中的 url。这样您就可以防止调用 javascript 标签并指定有效的文件扩展名。

        【讨论】:

          【解决方案5】:

          您所描述的内容可能容易受到 XSS(跨站点脚本)攻击。从本质上讲,恶意用户可能能够注入可能做坏事的 javascript 代码,同时作为您的站点执行。

          有关此攻击向量的示例,请查看:http://jarlsberg.appspot.com/part2#2__stored_xss_via_html_attribute

          编辑:听起来您已经在保护自己免受 SQL 注入和 XSS 的侵害,并且您想知道是否有某种方法可以让某人将 PHP 代码注入您的站点。我认为这是不可能的,因为您的服务器端代码不会执行此字符串。您只是指示客户端浏览器从 URL 下载图像。

          某人可能会链接到一个感染了病毒的图像文件,这会感染您网站的其他访问者,但不会影响网站本身。

          【讨论】:

          • 很高兴能帮上忙。如果您认为这最能回答您的问题,请考虑通过单击旁边的复选标记将其标记为“已接受”答案。
          【解决方案6】:

          在插入数据库之前,使用 imagemagik 验证照片是真实图像,而不是其他图像,你应该没问题。

          【讨论】:

          【解决方案7】:

          您应该考虑的一件事 - 我可以将我的“超高分辨率”图像与大约 200 兆图像关联起来。我想这可能会破坏您网站的加载体验(取决于设计)。 所以除了“脚本攻击”之外,允许用户将内容链接到您的网站总是有问题的。

          【讨论】:

            【解决方案8】:

            通过上传“某处”,您会将文件托管在您的网络服务器上吗?

            有很多潜在的问题:

            <img src="http://hacker.ru/badtimes.php" />
            <img src="javascript:alert(String.fromCharCode(88,83,83))" />
            

            另外,特制的 jpg 可以感染用户的机器: http://www.microsoft.com/technet/security/bulletin/ms04-028.mspx

            【讨论】:

            • 好吧,假设他们把 URL 像这样&lt;img src="http://hacker.ru/badtimes.php" /&gt;,它可以对我的网站做什么?
            • 损害的不是您的网站,而是您的用户。想象一下,您已经登录了您的银行,然后恶意行为者能够将此图像嵌入您的网站,以便您的所有访问者都加载它。现在,假设恶意图像是这样的,而不是&lt;img src="http://yourbank.com/transfer?to=maliciousaccount&amp;amount=100 /&gt;
            【解决方案9】:

            除了其他人所说的邪恶意图之外,我能看到的唯一另一个问题是图片是否真的很可怕,但是这可能发生在任何可以上传图片的网站上。

            如果你真的允许用户上传图片,你可以检查 mime 类型(PHP 的 getimagesize() 函数可以给你这个信息)。这也不是万无一失的,但比只检查扩展要好。

            【讨论】:

              【解决方案10】:

              不,这根本不安全,XSS攻击可以通过图片标签执行。

              一个简单的例子是:

              <IMG SRC=j&#X41vascript:alert('test2')>
              

              http://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29

              【讨论】:

              • 这是假设用户在提供图片时可以控制图片的名称。
              • 此警告框适用于哪些浏览器?当我尝试时,IE 或 Firefox 中没有任何反应?
              • 这里的简单示例:jsbin.com/avuda 它在 Firefox、IE 8 或 Chrome 中不起作用
              • @Stuart:问题是用户提供的是 URI,而不是文件,因此他们可以完全控制。
              • @Martin:大多数浏览器的最新版本现在都明确拒绝图像的 javascript URI——但仍然存在易受攻击的 URI。
              【解决方案11】:

              假设您已经对 SQL 注入进行了清理。您需要阻止用户执行以下操作:

              <img src="http://usmilitary/launchAllNukes?When=Now" />
              

              或:

              <img src""<script>//Evil code</script>" height="123px" width="123px" />
              

              【讨论】:

              • 对于第一个示例,如果不访问该站点并查看其中的内容,就无法验证此类内容。那,任何为响应 GET 查询而做出不可逆转和重要的事情的人都应该得到他们所得到的。 (有规则说您应该为此使用 POST。)第二个示例将被简单地在输出之前对“url”进行 HTML 转义而失败。
              • @cHao 真的。我的观点是,他需要先对 url 进行 SQL 转义,然后再将其放入 DB,然后 HTML 对其进行转义,然后再将其放入 HTML 页面,最后您可以考虑先测试 url 以确保它返回图像(可能使确保它的大小合理)。当然,您是正确的,目标站点有责任确保它只在 POST 而不是 GET 上进行更改,但并非所有人都这样做,所以理论上这个过程可能会发生一些不好的事情。
              【解决方案12】:

              检查文件扩展名没有意义,因为这并不能保证它不会被脚本处理。 GET 请求(由 img src 使用)应该是安全的,并且不应导致重大状态更改(例如购买、删除用户等)。但是,有一些错误的网站会这样做。

              因此,最安全的解决方案是要求用户将图片上传到您的网站。如果您确实允许远程图像,您至少应该需要httphttps 方案。

              【讨论】:

                猜你喜欢
                • 2019-02-25
                • 2011-06-16
                • 2023-04-09
                • 2011-02-07
                • 2011-04-02
                • 1970-01-01
                • 1970-01-01
                • 2023-04-10
                • 2015-07-31
                相关资源
                最近更新 更多