图片路径(img src)会导致某些“坏”的事情发生吗?

27

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

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


3
在将照片插入数据库之前,请使用ImageMagick验证该照片是否是真实的图像,而不是其他内容,这样就应该没问题了。 - Byron Whitlock
“这是完全安全的吗?” 完全不安全 :) 如果没有其他措施,所有类型的xss攻击都可能在此处发生。 @Byron 这是一个好方法,假设imagemagick是安全的,但如果它不是银行网站,那么这不是真正的威胁。 - kubal5003
<img src="<?=htmlspecialchars($photo);?>" height="123px" width="123px">">。这个代码没有保护XSRF(跨站请求伪造)的安全问题,如果用户输入/logout.php作为图片URI很可能会造成问题。 - Frank Farmer
3
@Byron:即使脚本检查时图像是有效的,稍后在图像主机上用恶意内容替换照片也是轻而易举的。 - Marc B
@Marc,正确。我以为他是将图像源代码下载到数据库中并提供字节服务。 - Byron Whitlock
12个回答

12

假设用户在图像被提供时可以控制其命名。 - Samantha Branham
1
这里有一个快速的例子:http://jsbin.com/avuda 在Firefox,IE 8或Chrome中无法工作。 - Earlz
1
@Stuart:问题说用户提供URI而不是文件,因此他们拥有完全控制权。 - Quentin
3
@Martin:目前大多数浏览器的最新版本都明确拒绝使用JavaScript URI来加载图片 - 尽管仍然存在一些易受攻击的浏览器。 - Quentin
@David 哦,好的,知道了。这就解释了为什么它对我不起作用,谢谢。 - Martin Smith
显示剩余2条评论

12
您所描述的可能存在XSS(跨站点脚本攻击)漏洞。恶意用户可以注入JavaScript代码,从而在您的网站上执行坏事。
例如此攻击向量,请查看:http://jarlsberg.appspot.com/part2#2__stored_xss_via_html_attribute 编辑:听起来您已经保护自己免受SQL注入和XSS攻击,您想知道是否有某种方式可以让某人将PHP代码注入到您的网站中。我认为这是不可能的,因为您的服务器端代码不会执行此字符串。您只是指示客户端浏览器从URL下载图像。
可能有人会链接到带有病毒的图像文件,这将感染其他访问者的站点,但不会影响该站点本身。

我很高兴能够帮助您。如果您认为这是最佳答案,请考虑通过点击旁边的复选标记将其标记为“已接受”的答案。 - pkaeding

6

有一件事情你需要考虑——我可以给你提供一个大约200兆的“XUltra高清”图片链接。我猜这可能会影响你网站的加载体验(取决于设计)。 因此,除了“脚本攻击”之外,允许用户在你的网站中插入链接内容也是有问题的。


5

需要做的几件事情是验证它是一个被接受格式(通常为jpg、png和gif)的真实图像,并对文件名进行清理和更改。

您可以使用PHP getimagesize函数来检查它是否是有效的图片,以及它的格式。当文件上传时,您会收到所谓的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获取图像,保存到临时文件中,然后像上面描述的那样检查它是否真的是一个图像。这也可以捕捉到用户链接到不存在或无效的图像,所以你可以警告他们。此外,强制实施文件大小/尺寸限制——你不希望某个人在他们的个人资料中链接到一个5GB的图片(虽然这将是他们自己的带宽问题),因为这可能会影响你的其他用户。不过,用户随时都可以更改文件为其他内容。你可以每隔x小时检查一次,并警告那些正在进行可疑操作的人,但这似乎需要你付出很多努力。
你还可以强制执行文件名规则,比如文件名中不能有unicode,名称不能包含<>''""# -这些字符,在合法的图像URL中很少出现。

4
严格来说-可以。我可以在您的网站上发布一个由我的服务器托管的图像。
<img alt="Kobi's Photo" src="http://example.com/photo.jpg" />

看起来很无害,但实际上,每个访问者在您的网站上观看我的图片时都可以被跟踪和记录。每个访问者都会在我的服务器上获得一个会话,甚至可能会被分配一个 cookie(不是有趣的那种)。更糟糕的是,我可以跟踪每个显示我的照片的访问者的每个页面查看 - 浏览器通过 referer 标头发送每个显示照片的 URL。
让人们托管自己的照片,会泄露您访问者的一些隐私。


3
假设您已经对SQL注入进行了清理。您需要防止用户执行以下操作:
<img src="http://usmilitary/launchAllNukes?When=Now" />

或者:

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

2
关于第一个例子,没有办法在不访问网站并查看其内容的情况下验证这样的东西。此外,任何人对GET查询做出不可逆和有重大后果的响应都应该自认倒霉。(规则说你应该使用POST来处理这个问题。)第二个例子可以通过在输出之前对“url”进行HTML转义来避免。 - cHao
@cHao 对的。我的观点是他需要先对URL进行SQL转义,然后再在将其放入HTML页面之前进行HTML转义。最后,您可以考虑首先测试URL以确保它返回一张图像(可能确保其大小合理)。当然,你是正确的,这是目标网站的责任,确保只在POST而不是GET上进行更改,但并不是所有网站都这样做,因此在此过程中理论上可能会发生一些不好的事情。 - Adam

2
检查文件扩展名是没有意义的,因为这并不能保证它不会被脚本处理。GET请求(如img src中使用的)应该是安全的,并且不应该导致重大状态更改(例如购买、删除用户等)。然而,有些有缺陷的网站会这样做。
因此,最安全的解决方案是要求用户将图像上传到您的网站。如果您允许远程图像,则至少需要要求使用http或https协议。

2

在将图片插入数据库之前,使用ImageMagick来验证该图片是真实的图片,而不是其他类型的文件,那么您就应该没问题了。


一种验证远程图像的技术:https://dev59.com/zUvSa4cB1Zd3GeqPbyG5#2004122 - micahwittman
如果远程服务器在20秒内没有响应...你的页面渲染就会停滞吗? - Frank Farmer

2
如果您允许用户指定任何URL作为个人资料图片,则攻击者可能利用此来促进针对较小网站的拒绝服务攻击。它对目标网站的影响相当于被 slashdotted。例如,攻击者可以将其个人资料图片URL更改为托管在目标网站上的大型资源。每当您网站的访问者查看攻击者的个人资料时,目标网站都会浪费带宽将资源提供给访问者。
解决方法是只允许链接到图像托管网站的个人资料图片URL。

1
通过在“某处”上传,您是否将文件托管在您的Web服务器上?
存在许多潜在问题:
<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

1
好的,假设他们像这样放置URL <img src="http://hacker.ru/badtimes.php" />,它会对我的网站造成什么影响? - good_evening
损害不是针对您的网站,而是针对您的用户。想象一下,您已经登录到您的银行账户,然后一个恶意的攻击者能够嵌入这个图像到您的网站中,以便所有访问者都会加载它。现在,想象一下,这个恶意的图像实际上是这样的 <img src="http://yourbank.com/transfer?to=maliciousaccount&amount=100 /> - Juanda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接