Go Back   CodingForums.com > :: Server side development > PHP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 11-25-2008, 08:56 AM   PM User | #1
queirdo
New Coder

 
Join Date: Nov 2008
Posts: 16
Thanks: 1
Thanked 1 Time in 1 Post
queirdo is an unknown quantity at this point
Security in PHP file uploads - advice??

I'm building a content management system and need allow uploading files from a form. I generally know how to do file uploads, I've done it before, but I'm really just learning about security. I'm sure some of you know a lot more about this! So I'm asking for some information about potential security pitfalls, as the stuff I've read isn't 100% clear to me and I don't want my server at risk.

(Note: Not just anyone will be able to access the upload pages I'm creating. This part of my site is password protected, and I think the login is pretty secure... every page in this section runs an authorization script to check if they are logged in, and the session 'key' changes with every page load)

Okay, so I've found that I have to set the folder I'm uploading to with permissions 777 to allow access & get the upload to work. (I use the move_uploaded_file ($_FILES['uploadedfile']) method, not FTP). I will have a specific folder set aside for these files, but probably just in httpdocs, as I need to be able to allow any visitor to the site to download and see these files. But my main questions are: 1) Does just having a folder with CHMOD 777 pose a security risk and how can I make this safer? 2) Are there other security issues I should be aware of?
queirdo is offline   Reply With Quote
Old 11-25-2008, 09:23 AM   PM User | #2
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
644 will suffice, not 777, thats way too open. As long as you're apache user can read and write than you're good.

Risks include improper checking of you're filetypes. This is why its often recommended to use a directory above you're httpdocs or public_html or whatever you're serving directory is. If you allow people to upload files that can be executed by the server it will do so when accessed directly. Huge security hole right there.
Always check both the extension and the provided mime type. Filesize checking could be useful as well depending on the type of data you're dealing with.

The best solution is an above root directory that web users cannot (easily) access. Chmod 600 or 644 and move files into there. This lets you write a script to handle the downloads from the directory, and control how users can access them.
Trust me, you'll smile the first time someone sneaks through a PHP file with a #!/usr/bin/php in it.
__________________
As of PHP 5.5, the MySQL library has been officially deprecated. It is recommended to move to either MySQLi or PDO libraries for your mysql connectivity. See here for help choosing which interface you prefer: http://php.net/manual/en/mysqlinfo.api.choosing.php
Fou-Lu is offline   Reply With Quote
Old 11-25-2008, 11:42 AM   PM User | #3
queirdo
New Coder

 
Join Date: Nov 2008
Posts: 16
Thanks: 1
Thanked 1 Time in 1 Post
queirdo is an unknown quantity at this point
Okay, I must be doing something wrong because 644 does not work for me. I get this error:

Warning: move_uploaded_file(../files/1d61f8f8dcc1e5a-med.jpg) [function.move-uploaded-file]: failed to open stream: Permission denied in /var/www/vhosts/domain.com/httpdocs/editor/fileuploading.php on line 59

Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '/tmp/phps0txPN' to '../files/1d61f8f8dcc1e5a-med.jpg' in /var/www/vhosts/domain.com/httpdocs/editor/fileuploading.php on line 59

I'm assuming this is a permissions problem. Is this the way my server is set up? What do I need to change to make this work?

Also, what is the exact danger in setting a folder to 777? I'm not saying I should do it, I would just like to better understand the threat.

I do intend to check for specific file types, but is it really necessary to have a folder above the root if only a handful of trusted people have login access to the upload form? It would just be easier for me to set up and access if it was in httpdocs, but if this is necessary I will do it.

Thanks for responding!
queirdo is offline   Reply With Quote
Old 11-25-2008, 11:49 AM   PM User | #4
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
You'll need to change the group, looks like its probably falling into the everybody group so it has readonly access. Chances are the user's Apache:Apache, so you can use a chgrp to change the group ownership to Apache and permissions to 664. To test out the ownership, use PHP and mkdir to create a new directory and see who owns it. Or you can use you're ftp client, ssh whatever to see who owns it.

The problem with 777 is on shared hosting. You pretty much give free access to anybody that's on the same network as you, which is not too cool.

Moving the directory is a security measure thats to prevent users from uploading malicious code. While not failsafe, it certainly helps. If a user uploads a PHP script which is accessable from a web directory, it will execute on the server which can really be a bother (foreach(glob('*') AS $file) unlink($file);). If its for just text files and images and only by trusted users, you *may* get away without an above root directory. I'd still do it though, I don't trust any user.
__________________
As of PHP 5.5, the MySQL library has been officially deprecated. It is recommended to move to either MySQLi or PDO libraries for your mysql connectivity. See here for help choosing which interface you prefer: http://php.net/manual/en/mysqlinfo.api.choosing.php
Fou-Lu is offline   Reply With Quote
Old 11-25-2008, 09:59 PM   PM User | #5
queirdo
New Coder

 
Join Date: Nov 2008
Posts: 16
Thanks: 1
Thanked 1 Time in 1 Post
queirdo is an unknown quantity at this point
I know I can change the permissions to 644 in an FTP program, but I don't think I can change the ownership that way... I have really been trying to figure this out but I know next to nothing about server administration and everything I can find to read seems to skip over the very basics.

I understand the concept of the groups and ownership (I think). My php script is considered a 'user' and if that user is not the owner of that directory, it's not allowed to write to it.
What I don't know how to do:
1) How do I find out the 'user' name of the php script? Is it always apache, or is there a way to check it?
2) How do I change the owner of the directory? I can look up the right line of code easily, but I have never used shell to directly mess around with the server (wouldn't I have to do that?) - I know nothing about how to do this. I do have the *ability* to access the server, (it is a virtual dedicated server which I own and use exclusively), but not the *knowledge* of how to do this. I have only ever needed to do the most basic server management through Plesk, and I'm not sure if there is a simple way to do this through the Plesk interface but I couldn't see one.

Can anyone walk me through this or point me to good basics resources?
queirdo is offline   Reply With Quote
Old 11-26-2008, 12:14 AM   PM User | #6
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
The easiest way to perform this task is with a mkdir command through PHP. Best to my knowledge, it will default the user:group as you're apache user (since it can be anything), and you can chmod and chown it to yourself at that point (depending on what you need for personal privilege).
PHP Code:
mkdir('/home/{username}/MyDir'0664);
chown('/home/{username}/MyDir''{username}'); 
Doing it from the shell is similar, the command calls used by PHP are almost identical to those used by linux.
__________________
As of PHP 5.5, the MySQL library has been officially deprecated. It is recommended to move to either MySQLi or PDO libraries for your mysql connectivity. See here for help choosing which interface you prefer: http://php.net/manual/en/mysqlinfo.api.choosing.php
Fou-Lu is offline   Reply With Quote
Old 11-26-2008, 12:47 AM   PM User | #7
queirdo
New Coder

 
Join Date: Nov 2008
Posts: 16
Thanks: 1
Thanked 1 Time in 1 Post
queirdo is an unknown quantity at this point
Permission denied

It doesn't let me make a directory.

Since I have a virtual private server and am the only one using it, would it be a huge security risk to just set the folder to 777 and put an .htaccess file in there that doesn't allow php or CGI files to be run? On top of checking in the upload page to make sure they only upload accepted file types? It seems like it could be an easier way to solve the problem.
queirdo is offline   Reply With Quote
Old 11-26-2008, 09:51 AM   PM User | #8
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,635
Thanks: 4
Thanked 2,448 Times in 2,417 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
I guess that option could work. Max you're permissions at 666 though, don't allow execution privilege.
You can't create an above directory directory or file if you can't actually write to it. You can temp that up by allowing everybody write privilege to the website root (one above you're public_html). MkDir then, then change the permissions back. That will at least tell you who you're apache user is.
__________________
As of PHP 5.5, the MySQL library has been officially deprecated. It is recommended to move to either MySQLi or PDO libraries for your mysql connectivity. See here for help choosing which interface you prefer: http://php.net/manual/en/mysqlinfo.api.choosing.php
Fou-Lu is offline   Reply With Quote
Reply

Bookmarks

Tags
file, permissions, php, security, upload

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 04:51 AM.


Advertisement
Log in to turn off these ads.