Php – Chmod for PHP web application

chmodPHP

Im writing web application. It's have:

  • index.php
  • /app – of course, with .htaccess but im not talking about it
  • /app/session – for sessions, session_save_path(/app/session) must be used on my server
  • /app/include – index.php includes files from this directory
  • /app/config – only .xml files, that files reads classes from scripts in include
  • /images, /styles etc.

My question is:
What is correct chmod settings for above directories? I know what is chmod (im working on Linux) and I know how I can change it, but I can't find useful informations about that. Only articles like "How i can change chmod to 777…

And I don't know who is owner, group and others. My page will be on shared web server, so I think owner is apache, and group is www-data, correct?

Please, tell me what chmod's must have directories (and files? I'm using -R for chmod to files) for safe website. Mainly it comes to the possibility of intrusion by any script.

Best Answer

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