Chmod for PHP web application Chmod for PHP web application php php

Chmod for PHP web application


Wordpress has a nice article explaining unix file permissions. Read it and you'll grasp the basics of it. In short (and not theoratically correct):

Unix systems designate 3 different 'roles': the user, the group and the world. Especially 'the world' seems to confuse people.

Every file AND directory (which are both nodes and as such not that different in Linux systems) is assigned to a user and a group. You can see the user and group as 'owners' of the specific file/directory (I'll talk about 'nodes' further on, because it doesn't really matter). File permissions define who can do what with the nodes. Example given:

The file index.php is assigned to user 'aso' and group 'www-data' and has file permission modus 644. This means that the user (6) has read and write permissions, the group has merely read permissions (4), as is 'the world' (the last 4 of the three digits).

Now first you have to understand that EVERY user on a *nix system is part of a group. The group name is sometimes the same as the user name, but A GROUP IS ANOTHER ENTITY. So it is possible that you have a user as well as a group named 'aso'.

File permssions are build from a 'bitmask' as follows: read permissions are designated by the digit 4, write by 2, and execute by 1. Any combination can be made from this. In example write and execute permissions are designated with 3 (write = 2, execute = 1), and read and execute permissions are designated with 5 (read = 4, execute = 1).

Let's see what this means, and I have to be as fair as to say that I cannot be complete in this matter. Please use Google if you want a complete story.

If I create a file on my *nix system it is automatically assigned to me (my user) and the group my user is part of. Having the permissions 644 this means that I (logged in with my own user) can read the file and can alter (write) it. But I do not have the execute (x) permissions. It doesn't matter however because this only applies to executable scripts (shell scripts, most of the times with a .sh extension). The group the file belongs to ('www-data') only has read permissions, so cannot alter the file. The 'world' also only has read permissions.

Please note that a user can be part of multiple groups, and as such *nix file permissions have a limited scope: you might want to assign write permissions to group 1, and only read permissions to group 2. In traditional file systems this is not possible. However file systems like reiserFS and Ext3 may use an extended ACL to accomplish stuff like that. That's another story however.

What does this all means? It's more easy then expected actually, as long as you understand what the assigned rights mean and what is the difference between a file node and a directory node.

Files

  • Read: Ability to read it's contents
  • Write: Ability to alter (write AND delete) it's contents
  • Execute: Ability to execute the file (execute a script, with all consequences possible)

Directories

  • Read: Ability to read it's content. Which means: list the node names, but NOT a nodes content, type, etc.
  • Write: Ability to add/delete files
  • Execute: Ability to list the it's content, including type, last modification date etc.

Back to your case. If you have a normal setup (a Linux server running Apache and PHP as a module) your files will be assigned to your ftp user and the group 'www-data' (the group Apache is running from). You yourself need read AND write permissions (as sometimes you want to change a file), but DO NOT NEED execute permissions (as PHP - or HTML for that matter - are not executables). So for the user, you'd need a 6 (read = 4, write = 2, combined makes 6). For the group user you only need read permissions, as Apache (or the PHP module) only need to read the contents of your php script. Any other user on the system has nothing to do with your files, and as such need no permissions as all (0).

So, for ALL your scripts, permissions of 640 (read and write for the user, read for the group and none for 'the world') are sufficient.

For the directories your user needs all permissions (read = 4, write = 2, execute = 1, 7 in total). Why? Because it needs to read it's contents (node names), has to be able to determine if it's a file or directory node (and other properties) AND has to be able to add and delete files (you want to add files sometimes, don't you?). So we'll giver your user a 7.

The group however ('www-data', the group Apache is running from) only need read and execute permissions. The read permissions to list the contents (node names) and the execute permissins to list other properties (node type, modification time etc.). It doesn't need write permissions though, because normally you don't want PHP (Apache) to add/delete files from your application tree.

Lastly the 'world', which is every other user on the system (that's NOT the same as the world in it's broadest sense) doesn't need any permissions. Why would anyone else on the server need access to your files?

Combined that would make 750 (all permissions for the user, read and execute for the group, none for others).


Summarized answer to your question, the bare minimum is:

  • File permissions: 640
  • Directory permissions: 750

But always good, quite standard and secure enough:

  • File permissions: 644
  • Directory permissions: 755


I use 640 on my server. The files are owned by me so I need read and write. Group is www-data so apache can read. PHP scripts don't need execute to run (if using the apache php module which is default. I think you need execute when using cgi), only read. No one else needs access. I have an uploads folder that gives apache write but just that one folder and I typically deny access with .htaccess, disable php to prevent script uploads or put it outside the webroot; depending on the needs of the project.