good_evening
good_evening

Reputation: 21749

Can something "bad" happen via img src?

I know, I know, title is quite bad, but I'll try to explain what I mean here. So, I ask my members to show their photos. They upload it somewhere, then paste their photos' URL into input and I save it to my database (MYSQL). Then, the photo is being seen on their profiles. I get the URL from database and do something like that: <img src="<?=$photo;?>" height="123px" width="123px">"> where $photo is URL taken from MYSQL. Is it totally safe? Can somebody upload for example .php file and harm my website? Do I need to check if URL's ending is .gif, .png, .jpg?
Thank you.

Edit: Yeah, of course I would protect my website from SQL injections and XSS attacks. But is there any way to harm my website in other way?

Upvotes: 27

Views: 22136

Answers (12)

willoller
willoller

Reputation: 7330

By uploading "somewhere", will you be hosting the files on your webserver?

There are lots of potential issues:

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

Plus, specially-crafted jpgs can infect users machines:
https://learn.microsoft.com/en-us/security-updates/SecurityBulletins/2004/ms04-028

Upvotes: 2

Kobi
Kobi

Reputation: 138017

Strictly speaking - yes. I can post an image in your site that is hosted by my server.

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

Seems innocent enough, but in fact, every visitor in your site, watching my image, can be tracked and recorded. Every visitor will get a session in my server, and and can even be given a cookie (not the fun kind). To make things even worse, I can track every page view of your visitors that displays my photo - the browser sends each url where the photo is display via the referer header.
By letting people hosting their own photos, you give away some privacy of your visitors.

Upvotes: 5

Siqi Lin
Siqi Lin

Reputation: 1257

If you allow users to specify any URL as a profile image, an attacker could exploit that to facilitate a denial of service attack against a smaller website. Its impact to the targeted website is equivalent to being slashdotted. For example, an attacker could change his/her profile picture URL to a large resource hosted on the targeted website. Each time a visitor to your site sees the attacker's profile, the targeted website wastes bandwidth serving the resource to the visitor.

A solution to this would be to only allow profile picture URLs that link to image hosting sites.

Upvotes: 2

JAL
JAL

Reputation: 21563

A couple of things to do are to validate that it is a real image in an accepted format (tpyically jpg,png and gif), and sanitize and change the filename.

You can use the PHP getimagesize function to check if it's a valid picture, and which format. You receive the alleged MIME type when the file is uploaded, but that is useless for validation. So, the following should work as the getimagesize function also validates images and returns the exif type.

$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.
   }

In your upload processing, giving your file a new unique name that you have chosen is a good idea, and then you don't have to worry about them doing anything strange with the filename.

Edit: I noticed you are referring to users supplying a URL to an image.

The answer I gave related to accepting, storing and displaying images users upload to your server.

The same principles apply, though, for displaying a URL of an image. You can get the image via cURL or fopen, save it to a temp file, and then check if it's really an image as described above. This can also catch the user linking to a non-existant or invalid image, so you could warn them. Also, enforce a filesize/dimension limit - you don't want someone linking to a 5 GB picture in their profile (though it would be their own bandwidth problem) as that could inconvenience your other users. The user could always change the file to something else later on, though. You could check once every x hours and warn people who are doing something suspicious, but that seems like a lot of effort on your end.

You can also enforce file name rules, say no unicode in file names, and the name must not include <>''""# -, which are characters that are rarely in legitimate image URLs.

Upvotes: 5

lintal
lintal

Reputation: 349

You could use a regular expression to filter the url in the PHP. That way you could prevent javascript tags being called and specify the valid file extensions.

Upvotes: -2

pkaeding
pkaeding

Reputation: 37633

What you described may be vulnerable to an XSS (Cross-site Scripting) attack. Essentially, a nefarious user may be able to inject javascript code that could do bad things, while executing as your site.

For an example of this attack vector, check out: http://jarlsberg.appspot.com/part2#2__stored_xss_via_html_attribute

EDIT: It sounds like you are already protecting yourself agains SQL injections and XSS, and you are wondering if there is some way for someone to inject PHP code into your site. I don't think this is possible, since your server-side code will not be executing this string. You are simply instructing the client browser to download an image from a URL.

It may be possible for someone to link to an image file that is infected with a virus, which would then infect other visitors to your site, but it would not affect the site itself.

Upvotes: 12

Byron Whitlock
Byron Whitlock

Reputation: 53861

Before inserting into the db, use imagemagik to validate that the photo is a real image, not something else, and you should be OK.

Upvotes: 2

ManniAT
ManniAT

Reputation: 2029

One thing you should consider - I could link you my "XUltra highres" image with about 200 megs. I guess this could break the loading experience of your site (depending on the design). So beside "script attacks" is allowing users to link content into your site always problematic.

Upvotes: 6

Rafael
Rafael

Reputation: 569

Besides what the others have said regarding nefarious intentions, the only other issue I can see is if the image is of something really horrible, but then that can happen on any website where you can upload images.

If you actually allow the users to upload images, you can check the mime type (PHP's getimagesize() function can give you this information). This is not bulletproof either, but better than just checking the extension.

Upvotes: 0

Damien Dennehy
Damien Dennehy

Reputation: 4064

No, it's not safe at all, XSS attacks can be executed through image tags.

A simple example would be:

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

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

Upvotes: 13

Adam
Adam

Reputation: 44929

Assuming you're already sanitizing for SQL injection. You need to prevent the user from doing something like this:

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

or:

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

Upvotes: 3

Matthew Flaschen
Matthew Flaschen

Reputation: 284796

There's no point in checking the file extension, as that doesn't guarantee it's not processed by a script. GET requests (as used by img src) should be safe, and should not cause a major state change (e.g. purchase, delete user, etc.). However, there are buggy sites that do so.

Thus, the safest solution is to require users to upload the image to your site. If you do allow remote images, you should at least require the http or https scheme.

Upvotes: 2

Related Questions