I am playing with my little PHP project right now and I am struck with a question about how I should approach the image handling. As far as I know, it's either you host the image in your server or let the user provide the link. Given my application is on a shared hosting site, which one better? What are the risks?
6 Answers
User provided
- You need to make sure the link is valid
- You need to check the content of the link to confirm its an image
- You need to be able to check the image on every load
- You have to build your html to check the image is still available.
- you would also have to confirm that the location of the image is a trusted location
- if the image is not on a HTTPS Server and you are, then you can cause issues with browsers.
Self Hosted Image
- You can make sure that the image is of the correct format.
- You need to watch out for exploits such as GIF Exploit
- You can manipulate the image with PHP Dynamically
- You can check and validate sizes of images and store on file-system or DB
- Requires more bandwidth
- If images are dynamic then they can cause high CPU
I would suggest that you go for self hosted image, OR host images on another data centre such as an image host with an open API.
If you your worried about bandwidth then you can create an image upload system that upon upload it uses an image host API to send the image to an external source and then store the image id in the database along with post/user/entity.
Stack Overflow uses the ImgUr for there images,SO has already thought about what your thinking of and have chosen to store externally but upload locally, ImgUR returns data that can be stored, Example below:
<images>
<image>
<name>imgur</name>
<title/>
<caption/>
<hash>UrTHG</hash>
<deletehash>bzEkpCdHPL22Hlp</deletehash>
<datetime>2010-08-14 03:39:23</datetime>
<type>image/gif</type>
<animated>false</animated>
<width>314</width>
<height>115</height>
<size>4413</size>
<views>0</views>
<bandwidth>0</bandwidth>
</image>
<links>
<original>http://imgur.com/UrTHG.gif</original>
<imgur_page>http://imgur.com/UrTHG</imgur_page>
<delete_page>http://imgur.com/delete/bzEkpCdHPL22Hlp</delete_page>
<small_square>http://imgur.com/UrTHGs.jpg</small_square>
<large_thumbnail>http://imgur.com/UrTHGl.jpg</large_thumbnail>
</links>
</images>
This is great because, thumbnails such as small_square,large_thumbnail etc are pre-generated along with meta data such as size,width,height, views etc.
If your worried about CPU usage and server-load then you should revert to the section above regarding external data storage.
If your worried about CPU then you can manipulate the image via GD Libraries and then store a cached version on file-system, update over intervals if need me.
Another down pointer to having user linked images is that when the image is it can be a dynamic image and loggin user data such as what pages that suer is visiting, this one if the main reasons that when your on Facebook and you embed an entity such as a blog post, the images are downloaded and stored on Facebook's CDN, so that outside sources cant tell what and where an IP is.
This should help you decide.
As there has been some discussion about the risk of XSS, i thought i would clear something up a little.
If you choose to allow the user to give you a link to an image you would have to validate the image and not so much the content, the reason why this has to be done is because lets say the user entered the following image location.
 javascript:alert('XSS');
If you do not sanitize via PHP with functions like htmlentities()
and HTML Purifier
library, after you store the above string in your database, when a user attempts to visit the page it would render like so:
<IMG SRC="  javascript:alert('XSS');">
So that every time the page renders you get a dialog box stating XSS
, thi is called an XSS Atack, the atack then cauld add another image "url" / "code" that sends certain data such as SESSION ID's to another site that automatically goes to your site and collects data under that ID.
if an attacker entered the following url http://attacker.com/evil.js
then the rendered content would be like so:
<IMG SRC="http://attacker.com/evil.js">
As this is an image tag then evil.js
would not be processed as javascript, because thats not how the Document Object Model is built, this would be safe to users.
Links on Vulnerabilities

- 56,863
- 21
- 114
- 161
-
One additional disadvantage of a user-provided image is that the user-provided image might contain some form of exploit. Sometimes people discover fatal bugs. Even a minimal amount of preprocessing (e.g. turn the image to a raw pixels and then save it in a particular format) will prevent those...unless your actual server is exploited by a bug in whatever code you are using to process the image yourself. – Brian Sep 14 '10 at 18:25
-
this would only be an issue if the url was not validated within the PHP Back End, if you see within **User provided** and the first bullet i say that the image url would have to be validated. – RobertPitt Sep 14 '10 at 18:29
-
1
-
2@Brian: There's more than one sort of thing that can go wrong. There are pictures on the Internet that I Do Not Want To See, that they don't sell brain bleach in large enough sizes for. – David Thornley Sep 14 '10 at 20:04
-
@David: This is an issue with self-hosted images too, though a more dangerous one for user-hosted, since user-hosted must be checked more than once...and the user can easily determine your IP address and present you a legitimate image. – Brian Sep 14 '10 at 21:41
-
One thing to be aware of if you are accepting URLs from your users and using them to build an <img>
tag: you have to be careful to not be vulnerable to Cross Site Scripting (XSS) attacks, which is an attack where a malicious user is able to inject their own code into your website.
For instance, let's say your code looks like:
$img_url_from_user = $_POST['image_url']; // user inputs a URL in a form
echo '<img src="' . $img_url_from_user . '" />';
A malicious user comes to your form and fills it out:
Now when PHP gets that input and uses it for $img_url_from_user
above, the resulting HTML the browser gets is
<img src="invalid.jpg" onerror="alert('attack!')" />
and when the page is loaded, you will see an alert (obviously an attacker can do much worse that this. For instance, they could collect cookies and then use an AJAX call to send the info to their own server). So you have to make sure you sanitize any input you get from your users!
Resources

- 1
- 1

- 91,582
- 23
- 169
- 153
-
i think your getting mixed up with your XSS, an JavaScript file disguised as an image would not be able to affect the active dom unless loaded in a script tag, forgive me if I'm wrong. – RobertPitt Sep 14 '10 at 18:18
-
1@Robert the javascript in the
tag can create a script element with an external source, and since the
is inside the page's DOM, it would have as much access as a – Daniel Vandersluis Sep 14 '10 at 18:19
-
can you provide an example, because the attribute onerror event fires if the image location provided is unavailable or invalid. that does not mean that the source would be affected by the content. – RobertPitt Sep 14 '10 at 18:21
-
1@RobertPitt: No, Daniel's point is a valid concern if the user is providing a link to an image. – Brian Sep 14 '10 at 18:21
-
@Robert `onerror` was just an example. `
` is another. The article I linked has a lot more examples. – Daniel Vandersluis Sep 14 '10 at 18:23
-
Your talking about user content in general where as im talking about the actual data from lets say. "http://somesite.com/images/fake.png"... this would have no affect, where as if the user entered ` javascript:alert('XSS');` into the url for an image and the PHP Back end did not validate it then yes, there's an XSS exploit, heres the XSS Kingdom and no image tags there show a linked external source | http://ha.ckers.org/xss.html – RobertPitt Sep 14 '10 at 18:25
-
@Robert yes an attacker could also mask a malicious script as an image (is that what you're talking about?) but that isn't what I was addressing in this answer. I'm talking just about XSS through the inputted URL. – Daniel Vandersluis Sep 14 '10 at 18:28
-
1@RobertPitt - he's talking about a malicious user providing the URL to an image. The "URL" that the malicious user input actually has JS in it. There is no image file uploaded. The invalid.jpg file in the example is nonexistent. It has nothing to do with the content of any files - the malicious JS is right there in the user's input when the web app asks for a URL to an image. – Jeff Sep 14 '10 at 18:28
-
Yes, so this is cleared up now, we was talking about 2 separate things, as the OP was addressing the storage of the image for some reason i thought you may have actually been talking about the actually "image file" and not the location string passed in via the user, nice discussion anyway. – RobertPitt Sep 14 '10 at 18:32
-
@RobertPitt the OP asked about users uploading files to their server vs users providing a URL for an image hosted elsewhere. I was discussing the issues with the latter. – Daniel Vandersluis Sep 14 '10 at 18:36
-
Yes I agree, if you wish to understand what the mix up was I have updated my post in accordance to this issue. – RobertPitt Sep 14 '10 at 18:42
One risk of having the app link-dependent is if the link dies, the image dies. One risk of keeping things on your server is, it's possible to disguise any content as an image file.

- 3,560
- 6
- 34
- 48
I highly recommend pushing your image requests to imgur.com because it appears to be a very reliable image host that cropped up a while back to help support Reddit.com in their need for image hosting. Imgur will allow you to link to images they host and they are completely free. They aren't like tinypic or other sites that will block your images later on.
The only drawback I can see is if someone has a problem with you using a site that also hosts a lot of free porn. Totally your call if you want to go there. It's an open door and anyone can upload anything... but it's stable and reliable so I use it for all my image hosting needs.

- 336
- 1
- 10
Another problem with using an external image URL is that (unless hotlinking is disabled on the server the url points to) you might be contributing to someone else's bandwidth problems because most users won't bother uploading the image to a free image hosting site by themselves if the image already exists somewhere in the internet.

- 886
- 1
- 6
- 11
Any time you display user-created content on a page, you need to treat it as though it's radioactive. This is a potential XSS vulnerability. Take a look at this cheat-sheet for examples. Some sample inputs that could compromise your users:
document.write('Gotcha!')
http://myserver.com/coolimage.png" onload="document.write('Gotcha!')
><a href=malicioussite.com>View user profile</a>

- 234,037
- 30
- 302
- 389