Check the content of file before upload - php

I have to check the Content of a zip/rar file before uploading to the server.
Let me explain the scenario.
There are 2 types of users in my web project:
1: Normal Registered user
2: Administrator of the Project
Any Registered user can Create Pages on our Project,also they can create Themes For Pages.
Here one of us suggested a feature that to upload the Theme as theme pack [Compressed in Zip/Rar File].
If it is a Administrator then it is ok,there is no more security constraints.
But i am afraid in the case of Normal Registered Users.
My Problems are :
Assume that a Registered User uploading a theme pack that contains some malicious Files [Including PHP file] that may hurt the system.
I know that it is posible to check the Contents after upload,but what will happen if the use executed the File before that?
Ex : a user uploading a theme pack : contains some PHP codes & other large files,First our system will extract the content of the Theme Pack: Assume that the extraction of large files takes some time,and the smaller PHP file already extracted.So that the user can RUN the PHP file First.
The above one is my noob soubt,Actually i dont know other sides.
Please help me to figure out this problem.
Is it possible to upload the ZIP file in a secure manner ?

You won't be able to check this client side unless, of course, you had some kind of plugin (for all browsers) that did the checking/uploading for you. You'll have to handle this on the server side.
Also, Admins can upload viruses just as easily as non-admins. Some user's don't even know their machine has more viruses than a shanty-town brothel.
EDIT: Also, how is the user going to execute their PHP file on your server before you've checked it unless you run that php file? This sounds like a recipe for disaster anyway. All it will take is for something to slip through the cracks and a malicious user will destroy your site. Allowing normal people to upload executable script to your server is asking for serious trouble.

Unpack it in directory, which can't be reached through the web, check, then move back to web-folder, where it should be.
Assuming that you have your website in directory /var/www/website and user content goes to /var/www/website/user and is reachable through www.website.com/user/ :
Create temporary dir in /tmp unpack there, check, move to /var/www/website/user
If you don't have access to /tmp, you can create /var/www/website/tmp and prohibit access to it using your server settings

you can create a folder for putting the zip file and unzip.
and disable the php execute for the folder. that can solve your problem

Related

What is the risk in file upload forms if I rename the file and move it somewhere else

I'm reading about security stuff for PHP and my biggest concern now is the users file upload form. I've read a lot that some users may upload files that seems to be something else by changing the extension or even manipulating the header and the mimetype. I understand this.
But my question is how will this be an issue if I rename any uploaded file and move it to a directory that they do not know.
Please let me know if this will be enough or not, and if not, just give me some headline of what extra security checks should I perform
Thanks a lot
It really depends on what your online application is looking to achieve. If you wish to limit access directly to files which are uploaded, then you should set the folder permissions for the parent folder of the uploaded area to block user access. Then in your database you can record to path and only host the files through the http response. This will ensure that no files are accessed which could be potentially harmful, and also that users can still upload what they feel. As an extra step, you could add an erroneous file extension to each file while it is hosted and then remove it when it is served.
You might run an antivirus scan daemon in the background like avscand, configured. for scanning and moving infected files to a quarantaine directory. This ought to prevent delivering infected files later back to the people. Configure automatic virus database updating. A bit back that I did do such things, so investigate.
A simple renaming of the file name to one with safe characters should be sufficient; per user separated of course.
To have a more secure site the following needs to happen:
Due to the nature of security, this list will need be updated every so often.
Set the upload_max_filesize to something sensible
Install an Antivirus on the server
Set the upload_tmp_dir to something sensible, that the user may not access. See Setting PHP tmp dir - PHP upload not working
Have your form you upload files (which you already have done)
Your form handler should:
Run a file command to get the type of the data without executing it
Reject random files
The PHP interpreter will validate the file size
Run the virus scanner on the file
Do a file rename to ensure the filename is clean (if you need to reference things, it is convenient to rename the file to the primary key of your attachments table)
Move the file to a location that isn't accessible by the client (but move it, so if a later upload comes in with the same name nothing happens)
When you move the files, ensure they don't have execute permissions

Security steps to be taken care while file uploads, as its said to be vulnerable when kept in root? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have been going through the file uploads through various tutorials and sources, found that uploading into root or any folder which is web accessible is a security issue and is advisable to keep the upload folder outside the root.
Now, if someone is on shared hosting server like Godaddy, the user will not be having access outside the root folder.
And if really nothing can be done, how these open source software like Wordpress, Joomla, Drupal keep their uploads securely, and almost very much sure about the security?
The thing is what all has to be taken care, to save data securely on web when the condition is that, we only have option to keep our files within root.
Few checklist which i know for secure file uploads when you are forced to keep your files within the public accessible area are as follows:-
Functions to Check Uploaded File Size and Type.
While storing files rename the file to some random names and track the filename through database, md5 and sha1 is great.
Disable Script Execution with .htaccess.
This is an example for calling the uploaded files:-
// this is just example only to show how we can get the files
$imgfile = $rsPhoto['photo']; // or value from database
list($width, $height, $type, $attr) = getimagesize($imgfile);
switch ($type)
{
case 1: $im = imagecreatefromgif($imgfile);
header("Content-type: image/gif");
break;
case 2:
$im = imagecreatefromjpeg($imgfile);
header("Content-type: image/jpeg");
break;
case 3:
$im = imagecreatefrompng($imgfile);
header("Content-type: image/png");
break;
}
This is an example, it is not about saving few image files and retrieving it, the data's as we all know categorized in crucial elements of any business success.. so when such kinds of critical and important data has to be handled, what all options we have to make things perfect and secure as possible?
References:-
Implementing Secure File Upload in PHP
EDIT 1:
Is it a good idea to permanently redirect the domain to a sub folder of your domain...
So that your root is / but after redirection your root is /main-website/.
So if i keep my upload folder in /upload/, i think it will be assumed as outside the web accessible/public area...??
Hence my domain www.xyz.com points to /main-website/, And the upload folder is out of the scope of this domain...
Just a thought came to my mind so putting it up
Thanks.
I will assume that the uploaded files must be World readable. I will assume too that the file can be of any type: pdf, images (pdf, png, ico), documents (docx, xls), etc
The best solution here (generic that not just applies for PHP projects, but web projects in general) is to add a layer of complexity or a layer of redirection: You will save the file with a custom name self generated in the server, and use a BBDD to store the original file name.
Ok, let's see it by example. Imagine we have this directories:
/ -> Root. Its World Readable
/files -> Where we will store your files. World Readable too.
So, when I upload a file to your site named "foo.png", you will save it to "/files" directory, but you must change the name of my file to a auto generated one[1]. Let's say "1234asd". You must write in a BBDD a new record with the old file name ("foo.png") with the new auto-generated one. So... now, ¿how can I download my file if I don't know the new name?
Well, you must create "/file.php" in you server, that will accept GET parameter called "filename". Then I can do: "/file.php?filename=foo.png" and your code will do the follow:
Search in the BBDD if the file "foo.png" exists. If exists, get the name of the real filename. If not exist just return a 404 HTTP Code.
Then read the file from the direcory "/files/1234asd" and return it to the user
This way, any kind of files can be uploaded to you server (*.php files too), and you are secured, because the files are not accessed directly, but throw you PHP code (file.php).
This offers additional advantages like being able to check if a user have permission to read the file he is requesting (by implementing some kind of simple authentication). If the file is not found instead of return a ugly 404 HTTP code (that it's the correct stuff to do in that case) you can return a custom error message saying "ooops! 404 - The file you request is not available" or something like that.
Note: this solution applies to a files from 0 to maybe.... 10MB-20MB. If you are working with larger files, this solution is not optimal, and another approach should be take.
[1] http://php.net/manual/en/function.uniqid.php
Here's a link to (the google cached text only version) an article that is useful in helping secure wordpress.
http://webcache.googleusercontent.com/search?q=cache:V5RddpaOH4IJ:gerry.ws/2008/10/152/setup-and-secure-your-wordpress-upload-directory.html&hl=en&gl=au&strip=1
(i've linked to the google cache version becuase their site makes my chrome/firefox lock up, text only doesn't).
Basically you put your uploads in a location that only the app can access it (above or outside the web location) and then:
limiting the mimetypes of file that can be uploaded (and validating the files to make sure they don't contain known buffer overruns, exploits like exif poisining, embedded executables, etc)
make sure you aren't allowing parent paths
make sure that your upload path calculation is run server side not through some sort of hidden form field etc
make sure the execute access of your server platform (e.g. php/apache) won't execute in that location
make sure that only the web server (e.g. apache) account has rights to write to the location
make sure your scripts validate the data being posted in the upload
see also: http://codex.wordpress.org/Hardening_WordPress
Beside the methods to check file while upload it to your server like: check extension/mimetype, limit upload size... I have more tips bellow.
When I use shared hosting : turn off php execution in upload folder, you can use htaccess with php_flag=off.
When I have dedicated server: Setup a storage without any script(php) execution and upload file via ftp.
While you may not have access to any other folder outside root, typically on shared hosting you have access to your home directory.
I have tested on a server I have, and I can store files on /home/myuser which may be outside webroot (typically located in /home/youruser/www).
Also, you can use /tmp which is writtable for everyone, but if you do so, do not store sensitive data there, as it is readable by all users of hoster.

Free Directory viewer using PHP / Ajax that can unzip an uploaded file

I'm not sure if this is the best place to ask this question. However, I accept the possiblity of the question being moved/deleted.
I current have a website that does some file processing if a directory name is provided (local file system). I take the input in an HTML form. I'm looking to incorporate a script that allows the user to upload files / see the directory structure within the website directory. (Instead of them having to remember the name of the folder). However, most importantly, I'm looking for the two following features:
-Ability to be able to click and unzip a .zip or .rar file that they upload (Very important).
-Ability to perhaps incorporate the project as a sidebar using frames (Not that important, I could modify the scripts index page, if I have to).
A really good script, I found online was http://www.filelistpro.com/features.html, however, the problem is that it doesn't handle the option for unzipping a file.
Ajaxplorer - Demo - login using demo/demo
More information - http://www.ajaxplorer.info

How to prevent users from accessing files on server?

I have an application that let users to upload files to server. All files are stored in one directory called Uploaded Files (which has Thumbnails directory inside).
What are the most common ways for preventing users to see these files ? I mean I don't want users to see the files by typing URL like /path_to_website/Uploaded Files/1.png.
On the other side, authorized users should be able to see the files by getting a page that contains paths to files, like: ../Uploaded Files/1.JPG, ../Uploaded Files/2.png, ../Uploaded Files/3.gif. These users should be able to see only the files that appear on the page they got, i.e. I want to prevent them to see ../Uploaded Files/823.gif for example.
Please help to understand how this kind of things are done these days.
Thanks a lot !!
You can move the images into a folder out side the public directory and then stream them in via PHP to the users who are allowed to view them. By using the method detailed in the PHP header() manual for a very basic output (see Example 1).
Otherwise you could put a .htaccess file in the folder containing:
deny from all
if you are running Apache, but you still need to stream it out through PHP.

PHP - Question about uploading & uploaded image file

I have read the following tutorial "Uploading Files To the Server Using PHP"
and have several questions related to the topics.
Q1> The tutorial mentions that
"Note that PHP must have write access
to $uploadDir or else the upload will
fail"
For me, I only allow the user to upload the file after the user has login to the website.
If we set that $uploadDir permission as 777, then everyone can have written permission to that folder. How to avoid this problems?
Also I am using WAMP as my testing bed, can I simulate the same case as a real web server?
Q2> In order to prevent Preventing direct access, the tutorial mentions:
"A better approach is to move the
upload directory away from your web
root. For example, the web root for
this site is:
/home/arman198/public_html/ to prevent
direct listing i can set the upload
directory to /home/arman198/upload/."
Now my problem is that how can I display the uploaded images on other website pages. Since, the upload is not accessible directly anymore? I need to display the uploaded image save personal headshot dynamically on other website page. Is it possible?
Thank you
It's a common problem.
All modern computers have a temporary files directory. On Linux/Unix it's /tmp, on Windows it's usually c:\temp. The OS install will have set permissions on that directory so that anyone can write files there but only privileged users can delete files that don't belong to them. This is where PHP will want to put an uploaded file; your application then has to move it elsewhere (this is the purpose of the move_uploaded_file() function). PHP under Windows may need upload_tmp_dir actually set in the php.ini file.
Once you have an uploaded file, you can shift it whereever you like, including to where the webserver can read it to serve it. The biggest problem with that it is awfully easy to put this directory inside your codebase. Don't do that. As soon as you do anything beyond editing the files inside the directory they are served from, it will be problematic. Trust me: I've dealt with a few times this in code I've inherited. It's easy to let your webserver load files from a location outside your codebase.
The other alternative is to produce a download script. That way the file need not be servable by the webserver at all. One disadvantage is that you don't get to leverage the web server's MIME translation, but then, that lets you control which types of image files are permitted.
For the second question, you can use a PHP script intead of direct access to the directory. Lets name it image.php. Lets assume that it can take a parameter id, like image.php?id=image_id. In that file you can get the id using superglobal array $_GET. Then you can search for images with that Id and just send it as response.
First one I'm not sure, but maybe play with .htaccess file.
And for the first question, try setting your permissions to 775. That should allow PHP to write the file to the directory without giving the general public write access.

Categories