5

A user recently reported to me that they could exploit the BBCode tag [img] that was available to them through the forums.

[img=http://url.to.external.file.ext][img]

Of course, it would show up as a broken image, however the browser would retrieve the file over there. I tested it myself and sure enough it was legit.

I'm not sure how to prevent this type of XSS injection other than downloading the image and checking if it is a legitimate image through PHP. This easily could be abused with a insanely huge file.

Are there any other solutions to this?

John Godspeed
  • 1,387
  • 2
  • 10
  • 16

2 Answers2

2

You could request the headers and check if the file is actually an image.

Edit:

Sorry that I couldn't answer in more depth; I was enjoying dinner.

There are two ways I see it:

  1. You check to see if the supplied address is actually a image when the post is submitted or viewed, you could accomplish this by checking the headers (making sure it's actually an image) or by using file extension. This isn't fool-proof and has some obvious issues (changing the image on the fly, etc.).
  2. Secure your site that even if there is a compromise with the [img] tag there is no real problem, for example: the malicious code can't use stolen cookies.
  3. Use a script that requests an external image and modifies the headers.

A basic way to check the remote files content type:

$Headers = get_headers('http://url.to.external.file.ext');
if($Headers[8] == 'text/html') {
    echo 'Wrong content type.';
    exit;
}
Jason Dietrich
  • 155
  • 1
  • 1
  • 8
  • Worked something out: `function lolfy($url) { $head = get_headers($url); if ($head['Content-Type'] == "image/jpeg" || $head['Content-Type'] == "image/x-png" || $head['Content-Type'] == "image/gif") { return $url; } else { return "boken"; } }` – John Godspeed Feb 14 '11 at 04:30
  • However, I realized that the server I am requesting the information from could easily spoof the content type when only I am requesting it. I don't think this is a safe approach. – John Godspeed Feb 14 '11 at 04:53
  • Use a script to request the external image but modify the headers yourself. For example: http://www.abdulqabiz.com/files/proxy.php.txt – Jason Dietrich Feb 14 '11 at 05:34
  • "Secure your site that even if there is a compromise with the [img] tag there is no real problem..." I think this is the best you can do. The others can be spoofed. – kehers Jun 23 '12 at 06:51
2

There's only two solutions to this problem. Either download the image and serve from your webserver, or only allow a white-list of url patterns for the images.

Some gotchas if you decide to download the images -

  1. Make sure you have a validation for the maximum file size. There are ways to stop the download if the file exceeds a certain size, but these are language specific.
  2. Check that the file is actually an image.
  3. If you store it on the hard-disk, be sure to rename it. You shouldn't allow the user to control the file name on the system.
  4. When you serve the images, use a throw-away domain, or use naked ip address to serve the images. If the browser is ever tricked in thinking the image is executable code, the same-origin policy will prevent further damage.
Jingshao Chen
  • 3,405
  • 2
  • 26
  • 34
Sripathi Krishnan
  • 30,948
  • 4
  • 76
  • 83