scripts embedded in images - php

I run a small browser MMO, and I have a problem where a couple users are embedding scripts into their profile images, and using them to make attacks against said users, and my game in general. Is there a way to protect against this, or do I need to start blocking people from being able to use their own custom images?
If it helps any, it's done in PHP/MySQL.

Most likely what is hapening is they are giving you a link to a script that is building the image and returning it on the fly, there is nothing aside from no allowing users to use external images, that you can do about it, one option to prevent it is to download and store the image on your server as opposed to linking to the external image.
--I decided to provide a sample
This image is created on the fly, the url I'm giving is: http://unkwndesign.com/profilePic.png:
alt text http://unkwndesign.com/profilePic.png
now, profilePic.png is a folder that when requested is providing index.php which, using gd, is getting the SO logo, and imposing your IP address over it, to be very clear here I AM NOT LOGING THIS OR ANY OTHER DATA the source for the index.php is:
<?php
$image = imagecreatefrompng("http://stackoverflow.com/Content/Img/stackoverflow-logo-250.png");
$font_size = 12;
$color = imagecolorallocate($image, 0,0,0);
ImageTTFText ($image, $font_size, 0, 55, 35, $color, "arial.ttf",$_SERVER['REMOTE_ADDR']);
header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
?>
Since I am returning an image, with a proper extension, and the proper mime-type there is no way to detect what I am doing.
If the server had downloaded my image and stored it locally the IP address would be that of the server, which would ruin the fun of doing it and likely prove to be enough of a discurageing factor to stop the behavior.

Try having GD process those images. If it throws errors, you know you have a problem. Since image upload is a relatively rare operation, it shouldn't cause load problems to do some kind of arbitrary manipulation.

Some of the most common practices for validating image integrity include checking the MIME type, or binary reading the first few bytes of an image. Although these are not the best, it's worth a try to fend some of them off.

Are you talking about the issue where IE will interpret an image with HTML tags in it as being an HTML page, thus allowing HTML and script injection from user-submitted images?
(The bug being that IE will do this even if you tell it the Content-Type is an image/ type. Microsoft have caused endless security disasters with this attempt to be ‘helpful’.)
If so, the usual solution is to serve user-submitted images from a different hostname, one which does not have access to cookies or scripting at the main hostname from which you serve your web application.
Be sure to lock down your virtual servers so that the image server and the app server are each only available from one particular hostname (and the app server must not be accessible via IP address).
This will fix the cross-site-scripting issues. You may still have cross-site-request-forgery requests to deal with, but that's a different problem and can be exploited without image-wrapped script-injection.

Related

Is it possible to store image on user's browser

On my main page there is a big size image (~6 MB). It's kind of map.
I would like to store that image in user's browser even if they close browser or restart their PC, is it possible somehow?
That image is used in CSS file if it matter.
My hosting has small bandwidth, so I would like to store that image as long as I can on user's browser
Thanks for any tips.
There are a few options for this, some more convoluted than others.
The most cross-browser way is to make sure you set your cache headers to long cache times, and keep the URL consistent (similar to #Petah's suggestion).
Some browsers support the HTML5 File API. You could use JavaScript to store images here if it's supported.
You could also use the HTML5 AppCache (also with limited support), but this means you have to be careful about how you structure your application - because the HTML page will be cached forever until the cache manifest changes.
You can also serialise your image as a Data URL (fairly well supported) and store that string locally somehow (localstorage, cookies), but since cookies have small size-limits, and you wouldn't want to store 6MB in the HTML 'cos the page would take forever to load, this is probably not a great option.
You should look up caching best practices:
https://developers.google.com/speed/docs/best-practices/caching
http://msdn.microsoft.com/en-us/library/aa478965.aspx
http://developer.yahoo.com/performance/rules.html
You will have to set the correct HTTP caching headers for that image. With them you will tell the browser (and any proxies in between) to hold on to that image for as long as possible. But that will not guarantee that once user has that image that he will have it forever. It could be deleted from the cache for numerous reasons (user clearing the cache, browser evicting it, ...).
Start with this google search. If you want something more specific, you will have to tell us what web server you are using.
If you are worried about bandwidth, why not upload image to some image service (there are number of those around the Internet), and include its url in your css?
There are some concerns with these (free) services you should keep an eye for:
some image hosting services will block rendering of image (usually with image with text "not allowed to...") if
included on other sites like in stylesheets, forums posts... so you have to choose the one that dosen't do that
load time for image may vary dramatically if it is a free service, which is no big deal since once loaded in clients browsers, it will be cached
service may be temporarily unavailable which may cause you inconvenience with your clients
Try this.. Please change the href= to your image path and download= to the name of the file to be saved or you can leave it blank
<a href="imagepath/image.jpg" download="myImage.jpg">Click here to
download image</a>

Src images and security

What about if I let users insert links to their own host's images, do I need to prevent any type of security issue?
To better exaplain, <img src="somedomain/somefile"/> in which case should make my site vulnerable?
One potential problem with allowing arbitrary image URLs is that the image's host could track all views and IP addresses. In a forum with little traffic that could put the image host in the position to identify specific users' IP addresses.
Another is that you don't control what is shown in the image. An image resource could be dynamic and show pretty much anything at any given time to any user.
Then there's the very remote risk of an image exploiting a vulnerability in a visitor's browser or image library. But those are exceedingly rare and likely to get patched quickly - I myself know of only one instance this has happened on a larger scale.
Stack Overflow with is massive reach and traffic still allows external images - from that I tend to deduce that the risks are somewhat manageable.
Still, if you want to make really sure, you're best off fetching the image resource, copying it using an image library (to make sure it's a real image and to strip any sensitive metadata), and storing it on your server.
Also if you're doing a simple string insertion into your markup someone could close the image tag and start a script tag or something like that. So you should be watching for script injection in whatever form the user gets to set such an image src attribute.
For example what if the image src was set to this:
myimagefile.jpg" /><script> ... </script>
You can see how that would get rid of the image tab altogether and start doing something else in a script tag. You need to make sure whatever they enter actually points to an image before you save it and start writing it out on live pages.
This style of script injection could for example read from a form on the page (maybe including personal information, login details, or session ids) and send end users info back to some bad hackers data collection point using jsonp.

External image link containing malware

My website allows users to attach external image to their post. Sometimes when the host server of the image has malware.
My website will have this google malware warning
http://media.photobucket.com/image/google%20malware%20warning/unfuccwittable/MalwareWarning.jpg
Is there anything i can do on my end to prevent this? Like a php code to check the image before allowing displaying of the image on my website?
There are several PHP functions that can check a file for whether it is an image.
To make 100% sure, you would have to take every incoming image, create a copy of it using the GD library, and save that copy.
That will make absolutely sure no malware can pass through.
However, images are likely to lose quality, because GD's JPG compressor is not as good as Photoshop's for example. Also there will be issues with transparent images (they can be sorted out though).
CMYK images will not work at all with this method, but that's rather good, seeing as Internet Explorer can't display them, anyway.
Sorry, i just created an account. It's not affecting my server, it's just that warning, people will not proceed on to the website. I tried to google seems to not be able to find anything.
I gotta say, there is NOTHING like posting a big red warning on your site to attract visitors.
Since your using PHP, all public images should be ran through php-gd. This will verify its an image or fail. Also, it will remove geotagging metadata (stuff that some people consider private)

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?
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.
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
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.
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.
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" />
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.
Before inserting into the db, use imagemagik to validate that the photo is a real image, not something else, and you should be OK.
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.
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.
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.
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:
http://www.microsoft.com/technet/security/bulletin/ms04-028.mspx
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.

how to make a user restrict to download?

I know this question is silly.
But as per our intelligent Client request, I am not able to answer his question. Any one help for this.
We are building a online tutoring site. where it contains pdf, .ppt, .doc formats files are uploaded for reading as course materials. His (Client) request is that user can read all the contents but they must not download the materials and use this.
That is all the documents must be opened in their browsers.
Is it possible? Any other ideas?
Any other ideas?
Explain to your client that the only way for a document to appear on a user's computer screen is for the document to exist on that user's computer.
In other words, viewing a document involves downloading it. Even supposing the software on the user's computer somehow makes it impossible for the user to directly manipulate an electronic copy of the material, the user can take out a digital camera and take a picture of the screen.
There are ways to make it difficult for the user to save a copy of the file. However, it's likely that this will do more harm (frustrating users) than good (preventing theft).
Some users may want to peruse the material at times when they do not have an internet connection, or may want to copy it onto their mobile device (for instance), but accessing the internet on their mobile device is expensive so they would like to do the download on their computer.
If you send the data to the client the client has effectively downloaded it. You can make this difficult, but not impossible.
The only sure way to prevent downloading is to prevent viewing.
If this is a copyright problem it should be solved with legalese, not software.
Here are some guide-lines you may consider:
Don't put direct link of files such as:
Download
Instead, try to generate your pdf dynamically or put a another encrypted medium for
downloading eg:
Download
2: Don't allow directory browsing, use htaccess file with following commands:
Deny from ALL
3: Not sure, but you may possibly allow file opening this way too:
$filename="/path/to/file.jpg"; //<-- specify the image file
if(file_exists($filename)){
header('Content-Length: '.filesize($filename])); //<-- sends filesize header
header('Content-Type: image/jpg'); //<-- send mime-type header
header('Content-Disposition: inline; filename="'.$filename.'";'); //<-- sends filename header
readfile($filename); //<--reads and outputs the file onto the output buffer
exit; //and exit
}
Note: above is just an example of image not pdf but you can modify it for your needs.
An online site does not necessarily mean it is a web site. You could write a custom client that accesses the data and displays it.
The data would need to be encrypted between the client and the server. It probably should not be sent 'in bulk' either.
The effort associated with developing that is prohibitive.
You could license the software that allows users to read books, page by page, that is part of the Safari Books Online web site.
As best I can tell, they take the pages that they are going to display and turn them into small images. These images look as if they are sent in a random order, and assembled by the browser via javascript.
These tactics won't stop a determined person from getting your clients content... but the effort is unlikely to be worth it.
You could put the docs into Google docs and embed the docs viewer into your site. Of course, there's no stopping people from taking screenshots, copy/pasting text, downloading HTML, etc.
What do you mean by "read" but not "download"?? Do you know that even if you disable cache (which by itself is a bad idea) won't restrict an eaaaasy right-click>view source, "save target as", etc.?
I mean, the best you can have is a flash reader that is harder to save the content from, and that means disabling selection and copying, but anyway, it doesn't forbid anything.
The only way to forbid download is to return HTTP 403 :)

Categories