PHP file renamed to JPG and uploaded to server a threat? - php

We have a server that has been compromised that is running WordPress and Magento and is running them on about 5 domains all on the same server.
The hacker has been uploading there malicious scripts through all the file-system in hundreds of locations. It is a nightmare at this stage and I am still unable to find the entry point.
I did just notice that one of our AJAX image upload fields allows me to rename a PHP file as a .jpg and upload the file to the server.
When I access the PHP .jpg file in the browser is serves a broken image.
So I am not sure if the hacker would be able to upload a PHP file here and access it as a PHP file or if it would just serve it as a broken image fore like it did for me in the browser?
Any ideas on how much of a security threat this could be? Could it potentially be my entry point where hacker gained initial access? Or is the fact it serves as a broken image instead of processing the PHP file when I load in my browser mean that its somewhat secure?
Any help appreciated, thank you

Hard to say if the hacker has done something without actually checking what's there.
Regarding how to secure future image uploads I would advice using a function like finfo in PHP http://php.net/manual/en/function.finfo-file.php to find if a file belongs to any of the approved mime types, which btw, you should restrict to only a limited type of image types.
Also you should consider not allowing the use of the original image, but instead an adjusted version of it, to avoid that users end up downloading huge images or things like that.
Answer:
Usually (depending on the web server configuration) no one can execute a PHP file if it has a different extension, they could have upload it, but they can't run it, at least in any common configuration.
So, in theory you should not have to worry for that specific thing, but do be worry that someone is spending time in trying to hack you and that means you should expend time protecting the site and server.
I would recommend searching for articles on how to protect your specific server and configuration and to make sure you update your software, OS and such to the latest security updates.

Being able to upload a file with .jpeg file extension but PHP content is not a vulnerability in itself. However:
if the attacker is writing all over the file system you might have an upload function with a directory traversal vulnerability which will need fixing, ideally by not letting the uploader choose their own filename at all;
there are other problems to do with cross-site-scripting when you let users upload content to be served from the same hostname as the site;
it may be worth checking an uploaded file using something like getimagesize() to ensure that you have a JPEG file and non-ridiculous dimensions, but given the possibility of ‘chameleon’ files that can be interpreted as multiple different types this is not necessarily watertight, so this is a ‘defense-in-depth’ measure at best.
Getting a web server to run a .jpeg file as PHP code could happen by:
being able to write to server configuration to associate .jpeg with the PHP handler. Typically this would happen because another vulnerable file upload feature allowed an attacker to write a .htaccess file in the same directory for Apache to pick up.
a PHP script with a Local File Inclusion security hole. Typically this would be code like:
include("include/$variable");
where an attacker can get content into $variable, to point to something.jpeg. Generally include/require should never be used with variables unless those variables are explicitly limited to a few known-good values.
The other likely possibility if you have a load of malicious pages uploaded to your server is that your server login is compromised.

Related

PHP data upload security and optimization [duplicate]

I am allowing users to upload files to my server. What possible security threats do I face and how can I eliminate them?
Let's say I am allowing users to upload images to my server either from their system or from net. Now to check even the size of these images I have to store them in my /tmp folder. Isn't it risky? How can I minimize the risk?
Also let's say I am using wget to download the images from the link that the users upload in my form. I first have to save those files in my server to check if they actually are images. Also what if a prankster gives me a URL and I end up downloading an entire website full of malware?
First of all, realize that uploading a file means that the user is giving you a lot of data in various formats, and that the user has full control over that data. That's even a concern for a normal form text field, file uploads are the same and a lot more. The first rule is: Don't trust any of it.
What you get from the user with a file upload:
the file data
a file name
a MIME type
These are the three main components of the file upload, and none of it is trustable.
Do not trust the MIME type in $_FILES['file']['type']. It's an entirely arbitrary, user supplied value.
Don't use the file name for anything important. It's an entirely arbitrary, user supplied value. You cannot trust the file extension or the name in general. Do not save the file to the server's hard disk using something like 'dir/' . $_FILES['file']['name']. If the name is '../../../passwd', you're overwriting files in other directories. Always generate a random name yourself to save the file as. If you want you can store the original file name in a database as meta data.
Never let anybody or anything access the file arbitrarily. For example, if an attacker uploads a malicious.php file to your server and you're storing it in the webroot directory of your site, a user can simply go to example.com/uploads/malicious.php to execute that file and run arbitrary PHP code on your server.
Never store arbitrary uploaded files anywhere publicly, always store them somewhere where only your application has access to them.
Only allow specific processes access to the files. If it's supposed to be an image file, only allow a script that reads images and resizes them to access the file directly. If this script has problems reading the file, it's probably not an image file, flag it and/or discard it. The same goes for other file types. If the file is supposed to be downloadable by other users, create a script that serves the file up for download and does nothing else with it.
If you don't know what file type you're dealing with, detect the MIME type of the file yourself and/or try to let a specific process open the file (e.g. let an image resize process try to resize the supposed image). Be careful here as well, if there's a vulnerability in that process, a maliciously crafted file may exploit it which may lead to security breaches (the most common example of such attacks is Adobe's PDF Reader).
To address your specific questions:
[T]o check even the size of these images I have to store them in my /tmp folder. Isn't it risky?
No. Just storing data in a file in a temp folder is not risky if you're not doing anything with that data. Data is just data, regardless of its contents. It's only risky if you're trying to execute the data or if a program is parsing the data which can be tricked into doing unexpected things by malicious data if the program contains parsing flaws.
Of course, having any sort of malicious data sitting around on the disk is more risky than having no malicious data anywhere. You never know who'll come along and do something with it. So you should validate any uploaded data and discard it as soon as possible if it doesn't pass validation.
What if a prankster gives me a url and I end up downloading an entire website full of malware?
It's up to you what exactly you download. One URL will result at most in one blob of data. If you are parsing that data and are downloading the content of more URLs based on that initial blob that's your problem. Don't do it. But even if you did, well, then you'd have a temp directory full of stuff. Again, this is not dangerous if you're not doing anything dangerous with that stuff.
1 simple scenario will be :
If you use a upload interface where there are no restrictions about the type of files allowed for upload then an attacker can upload a PHP or .NET file with malicious code that can lead to a server compromise.
refer:
http://www.acunetix.com/websitesecurity/upload-forms-threat.htm
Above link discusses the common issues
also refer:
http://php.net/manual/en/features.file-upload.php
Here are some of them:
When a file is uploaded to the server, PHP will set the variable $_FILES[‘uploadedfile’][‘type’] to the mime-type provided by the web browser the client is using. However, a file upload form validation cannot depend on this value only. A malicious user can easily upload files using a script or some other automated application that allows sending of HTTP POST requests, which allow him to send a fake mime-type.
It is almost impossible to compile a list that includes all possible extensions that an attacker can use. E.g. If the code is running in a hosted environment, usually such environments allow a large number of scripting languages, such as Perl, Python, Ruby etc, and the list can be endless.
A malicious user can easily bypass such check by uploading a file called “.htaccess”, which contains a line of code similar to the below: AddType application/x-httpd-php .jpg
There are common rules to avoid general issues with files upload:
Store uploaded files not under your website root folder - so users won't be able to rewrite your application files and directly access uploaded files (for example in /var/uploads while your app is in /var/www).
Store sanitated files names in database and physical files give name of file hash value (this also resolves issue of storing files duplicates - they'll have equal hashes).
To avoid issues with filesystem in case there are too many files in /var/uploads folder, consider to store files in folders tree like that:
file hash = 234wffqwdedqwdcs -> store it in /var/uploads/23/234wffqwdedqwdcs
common rule: /var/uploads/<first 2 hash letters>/<hash>
install nginx if you haven't done its already - it serves static like magic and its 'X-Accel-Redirect' header will allow you to serve files with permissions being checked first by custom script

Is scripting still possible after image have been resized with PHP?

I want to have an upload system on my website, where users can only upload images.
These images will be resized by PHP directly on upload, so the original image will not be stored.
Do I still have to worry about scripts like php, etc. executing from malicious images?
You still have the following attack vectors to consider:
The uploaded image will be stored for a certain time on the server and could be used for evil if there are bugs in your application.
Any byte trash uploaded as the image might trigger bugs in your resize code that reads the uploaded image, so it is important to stay up to date with this software or library.
Apart from that, the generated image should be considered safe.
Update:
Uploading images with PHP always results in a temporary file being created somewhere, possibly in an unknown "temporary file directory" location that everyone else on a shared host is also using. This file has a file name and possibly the malicious content. Although the filename is randomly generated, an attacker might be able to guess it and try to use it. On the other hand, you cannot protect yourself from this built-in php mechanism other than not to use unsafe include/require statements, because usually an attack requires a) getting evil code on your server and b) executing it.
Steps against it seem obvious: Configure a dedicated upload directory for your php. Secure it against code execution on the filesystem level by applying appropriate rights and restrictions. Don't mess with the random name generation. Keep this directory out of DOCUMENT_ROOT.
The second attack might be that an attacker tricks your code into reading a non-uploaded nonpublic file with the intent to reveal it's content. So it is a very good idea to check if the filename inside $_FILES really is an uploaded file before proceeding.

Securing Uploaded Files (php and html)

I have a simple site which allows users to upload files (among other things obviously). I am teaching myself php/html as I go along.
Currently the site has the following traits:
--When users register a folder is created in their name.
--All files the user uploads are placed in that folder (with a time stamp added to the name to avoid any issues with duplicates).
--When a file is uploaded information about it is stored in an SQL database.
simple stuff.
So, now my question is what steps do I need to take to:
Prevent google from archiving the uploaded files.
Prevent users from accessing the uploaded files unless they are logged in.
Prevent users from uploading malicious files.
Notes:
I would assume that B, would automatically achieve A. I can restrict users to only uploading files with .doc and .docx extensions. Would this be enough to save against C? I would assume not.
There is a number of things you want to do, and your question is quite broad.
For the Google indexing, you can work with the /robots.txt. You did not specify if you also want to apply ACL (Access Control List) to the files, so that might or might not be enough. Serving the files through a script might work, but you have to be very careful not to use include, require or similar things that might be tricked into executing code. You instead want to open the file, read it and serve it through File operations primitives.
Read about "path traversal". You want to avoid that, both in upload and in download (if you serve the file somehow).
The definition of "malicious files" is quite broad. Malicious for who? You could run an antivirus on the uplaod, for instance, if you are worried about your side being used to distribute malwares (you should). If you want to make sure that people can't harm the server, you have at the very least make sure they can only upload a bunch of filetypes. Checking extensions and mimetype is a beginning, but don't trust that (you can embed code in png and it's valid if it's included via include()).
Then there is the problem of XSS, if users can upload HTML contents or stuff that gets interpreted as such. Make sure to serve a content-disposition header and a non-html content type.
That's a start, but as you said there is much more.
Your biggest threat is going to be if a person manages to upload a file with a .php extension (or some other extension that results in server side scripting/processing). Any code in the file runs on your server with whatever permissions the web server has (varies by configuration).
If the end result of the uploads is just that you want to be able to serve the files as downloads (rather than let someone view them directly in the browser), you'd be well off to store the downloads in a non web-accessible directory, and serve the files via a script that forces a download and doesn't attempt to execute anything regardless of the extension (see http://php.net/header).
This also makes it much easier to facilitate only allowing downloads if a person is logged in, whereas before, you would need some .htaccess magic to achieve this.
You should not upload to webserver-serving directories if you do not want the files to be available.
I suggest you use X-Sendfile, which is a header that instructs the server to send a file to the user. Your PHP script called 'fetch so-and-so file' would do whatever authentication you have in place (I assume you have something already) and then return the header. So long as the web server can access the file, it will then serve the file.
See this question: Using X-Sendfile with Apache/PHP

which type of files are forbidden to upload

I want to put a section in my site where people can upload things and I was wondering which type of files I should forbid for them to upload.
This really depends on what you are going to do with the files. If you just store them, you could in theory accept even a collection of the world's worst computer viruses - as long as those files don't get executed.
As rogeriopvl suggests, better create a white-list of file types you want to allow.
Never rely on the MIME type that is sent with the browser. Always check the file type yourself, e.g. using getimagesize() if you want to allow only images.
A very good (but lengthy) discussion on the issue can be found here.
You must not ask what type of files are forbidden (black-listing), but what types of files are allowed (white-listing).
So write down what files you want your users to upload and make sure that your app checks if the files are in the allowed format.
Primarily your list should not include:
PHP files or any other scripting language file
Executable files
Checking the extension of the uploaded file isn't even half the story. There are file name syntax problems, type sniffing problems, script/plugin origin problems and more to worry about.
Making a file bucket that doesn't compromise the application is hard and not something to be undertaken lightly. As a starting point, consider serving files from a different [sub]domain to the file management application, and don't use a user-submitted filename as the basis for a filename on the server's filesystem.
(Please read the discussion at Pekka's link.)
Anything that could exploit your website or application, this would be php files (obviously), any sort of executable files, and illegal things you don't want to be liable for hosting.
I would implement a white list of file extensions you want to allow people to upload and check based on their Mime type and file extension and write a policy about what files can and cannot be uploaded to your site.
I would also store an IP address and other relevant data along with the file, just in case you need to block someone from using or abusing your system. It's a lot of work but letting users upload files to your site isn't something that should be taken lightly.

Security issue?

I am writing a small PHP application and I am not sure whether I have a security issue. So this is what the application does:
the user can upload either image files (png, gif, jpg, jpeg, tiff and a few others) or zip files
I check for mime-type and extension and if it's not an allowed I don't allow the upload (this is not the part I am worried about).
Now once uploaded I rename the file to a unique hash and store in a folder outside root access.
The user can now access the file through a short URL. I make the file accessible by setting the right mime-type for the header and then I just use readfile().
My question is whether the exploit where a jar file is included inside the image file works here? I am serving the image as a pure image.
If it does what are ways to prevent this?
Thanks.
MIME type checks will not solve the GIFAR issue. 2009's JREs are already patched, but if you want to solve the issue you can either
Serve your images from a different domain
Run a server side code to check if an image contains a valid JAR, like mentioned here
Anything else (short of denying the file to any Java enabled browser with an old enough JRE) may fail on specific cases.
Also remember that to perform a good attack with this technique your server infrastructure would have to be somewhat open (the fact that a request comes from the same domain doesn't mean that you should give any information it asks for.)
Checking the mime-type is not sufficient because that (or any other) HTTP header field can be forged. The best way to confirm that a file is a valid image is to attempt to read it as an image programatically. If it can be parsed as an image, you can be reasonably confident that it's not malicious code.
Related: ensuring uploaded files are safe
Any kind of hidden exploit like you describe should not affect the server because of the way you handle it. You're simply storing binary information, and retrieving binary information, without processing it in anyway. Browsers attempting to display exploited content might be at risk, but standard image types are fairly safe.
If you'd like to be safer, you could run an anti-virus on each uploaded file. If you're on a *nix platform, you can use the industry-standard ClamAV.
I'd be more worried of someone trying to upload a very large image file.
You can do 2 things. Serve your images from images.domain.com. this would have to be on another physical/virtual server, or firewall'd such that no open ports on the server can be accessed from that domain.
Or you can run the image file thru a java script (not javascript) like the one here. This will tell you if there is a jar file embedded in the image.
More info on this issue here:
http://www.gnucitizen.org/blog/java-jar-attacks-and-features/
I didn't actually even hear about this attack before your question, so first off, thanks for enlightening me! Googling around, it seems that there are basically two different attack vectors here. Both include the attacker luring "regular" users to a malicious site pointing to the masqueraded JAR file, and both have to do with the fact that the JAR will be executing in the "context" of your site (i.e. the origin will be your site).
First attack has to do with the applet being able to read user cookies, which basically means it'll be able to steal the user's login information for your domain.
The second one has to do with the fact that the applet is now allowed to open connections to other sockets within your domain, which is pretty bad if one of the users behind your server's firewall visits the malicious page (enabling the attacker to effectively bypass your firewall).
So this attack does not necessarily harm your server directly, but it does harm your users - and hopefully you care about your users. The two things you can do ensure their safety have already been mentioned in most of the other answers and are summarized on this page.

Categories