PHP question regarding fopen, fwrite and file permissions

jjones

Lifer
Oct 9, 2001
15,424
2
0
I have a need to create files in a folder that is located in the web root on an apache server using mod_php rather than cgi. Scripts creating files are running under the apache user, typically "nobody", and do not have authority to write in folders unless permissions are set to 777. This is obviously not very secure, especially when these folders are in the web root.

The solution I came up with was to do this:

Create a temp folder outside the web root with permissions set to 777. Then in the script I will be using, have a function write the necessary file to that folder, and then use PHP's built in FTP functions to copy that file, with a connection using the site owner, to the appropriate folder inside the web root that has properly set, secure permissions. When that is completed then the function continues on to delete the originally generated file in the temp folder and return success or failure.

That seems like a fairly secure way to handle this situation and I've tested it out successfully, but I'm wondering if anyone can point out flaws, or provide an alternate solution.

Edit: One thing I just thought of to enhance security is I can telnet in as superuser and chown the temp directory to the apache user and then chmod it to 600. Then only the apache user has access and the only worry there would be from other users on teh server, but since the server is dedicated, it only has the one server user anyway which is the site owner.
 

Superwormy

Golden Member
Feb 7, 2001
1,637
0
0
Why don't you store the files outside of the web root, and make a script that uses readfile() to pass the data through to the client when it is requested?
You could also use www.php.net/chmod to chmod the files to whatever permission you want them to have *after* you write them to the web root.
 

jjones

Lifer
Oct 9, 2001
15,424
2
0
While I could store the created files outside the web root, it's terribly inconvenient to do so in this application and is ultimately less secure than doing what I outlined above.

As for chmod, I do do that anyway using ftp_chmod but you can only chmod files if you are the owner and with files created by apache, "nobody" would still be the owner of those files and could do whatever it wants. Again, this is not a big deal because there is only one user on the server, but it's still not the most secure method of handling things. Using PHP's ftp functions the site owner, not apache is the file owner and then sets the permissions.

But thanks for your input! :)
 

QED

Diamond Member
Dec 16, 2005
3,428
3
0
What exactly are your security concerns and/or requirements?

Are you worried about anyone on the web viewing the files you created?
Are you worried about anyonee on the web modifying or destroying the files you created?
Are you worried about anyone on the web implementing a DOS attack by having Apache generate an inordinate
amount of files?
Are you worried about anyone on the web being able to create these files?
Are you worried about any web user viewing files created by another web user with this scheme?
Are you worried anyone with shell access from viewing, modifying, or deleting these files?



Why must these files be placed in a folder off of webroot? I'm guessing these will be somehow accessible to the
website user who created them, right?

I'm thinking your edited solution is perhaps the best available given what you've described thus far. You could enhance it a little by creating a new user account (with no login capabilities, of course) whose sole purpose is to own the folder that these files get
created in (in fact, make him chrooted to that folder) and to own the script that generates or places the file in the directory. Have the script's setuid bit turned on, so that when Apache runs it, it will run with the permissions of this new user. Make the files or directory readable only to the Apache userid. In this way, the files will only be readable through the website, and cannot be generated or deleted by any other means.
 

jjones

Lifer
Oct 9, 2001
15,424
2
0
Originally posted by: QED
You could enhance it a little by creating a new user account (with no login capabilities, of course) whose sole purpose is to own the folder that these files get
created in (in fact, make him chrooted to that folder) and to own the script that generates or places the file in the directory. Have the script's setuid bit turned on, so that when Apache runs it, it will run with the permissions of this new user. Make the files or directory readable only to the Apache userid. In this way, the files will only be readable through the website, and cannot be generated or deleted by any other means.
I like this. An added layer of security.

Regarding overall security, what I've described is pretty much the gist of it. I'm not very learned about permission issues but everything I've ever read says avoid giving world write permissions to folders and files, especially in the web root, so I'm trying to avoid that in as secure a manner as possible, while still providing the functionality I need.
 

QED

Diamond Member
Dec 16, 2005
3,428
3
0
Originally posted by: jjones
Originally posted by: QED
You could enhance it a little by creating a new user account (with no login capabilities, of course) whose sole purpose is to own the folder that these files get
created in (in fact, make him chrooted to that folder) and to own the script that generates or places the file in the directory. Have the script's setuid bit turned on, so that when Apache runs it, it will run with the permissions of this new user. Make the files or directory readable only to the Apache userid. In this way, the files will only be readable through the website, and cannot be generated or deleted by any other means.
I like this. An added layer of security.

Regarding overall security, what I've described is pretty much the gist of it. I'm not very learned about permission issues but everything I've ever read says avoid giving world write permissions to folders and files, especially in the web root, so I'm trying to avoid that in as secure a manner as possible, while still providing the functionality I need.

As you know, you should avoid world writable directories and files just about everywhere on a Unix system-- it's not just specific to the web root directory.

The simplest, yet still secure, solution is probably what you have already suggested: have the subdirectory owned by the Apache user, and lock it down so only that user can read/write from it. My proposal of adding a second user and making the script run with the new user's permissions adds an additional layer of security which might not be necessary in this case-- that additional layer being able to more easily restrict access to created files through the web server. However, if there is nothing secret or sensitive in these files, this is a bit overkill.
 

jjones

Lifer
Oct 9, 2001
15,424
2
0
I like what you suggested and it's easy enough to implement so I'll incorporate it into this. Thanks! :)
 

jjones

Lifer
Oct 9, 2001
15,424
2
0
Something I just realized as I'm learning more about Unix/Linux permissions, users, groups, etc. In the typical server setup, apache has access to read-execute throughout the web root, any user web root on the server. In a shared environment, the web root (usually the folder called www or public_html) is typically set to 750 with the user being the site owner (with read, write, execute), the group being the apache user (usually called "nobody" with read, execute), and no world permissions.

Does this mean that on a shared server, assuming I knew the other user names on the server, I could write a script to pull any directory and files inside the web root and read their contents, assuming the directories inside are set to 755 and files set to 644 as is common? Seems like I should be able to do that, or maybe I'm missing something.