I have noticed, that despite thousands of tutorials and blog posts about unix permissions, many people still don’t grasp the concept of it and think about permissions in the sense of qualitative numbers, where the lower is simply the better. I’ll be talking here specifically about permissions of a php web application, because most of misunderstandings I have encountered, come from this sphere.
Permissions are not just numbers
Yes, I know you know it, but I will nonetheless explain in short what the numbers mean.
Each of the three numbers stands for a specific group of users.
- The first number represents the owner of the file.
- The second number represents the group that is the owner of the file. By default it’s the primary group of the owner, but it can be set to anything if you have write access.
- The last number represents all the existing users of the system.
The first misunderstanding about permissions comes from the definition of the last digit: usually it is described as “everyone”. Well, it’s not just everyone in the universe, it’s meant as every enabled user on the system.
Each number is not just a qualifier, it has a specific meaning that can be calculated:
- 0 means no permissions at all.
- 1 means the permission to just execute the file
- 2 means the permission to just write to the file
- 3 means the permissions to both execute and write to the file
- 4 means the permission to read the file
- 5 means the permissions to both read and execute the file
- 6 means the permissions to both read and write to the file
- 7 means the permissions to read, execute and write to the file
Since executing a directory doesn’t mean much, in the directory context, execute should be read as “can enter the directory”.
Notice: In this article, I will ignore the existence of the sticky bit and other more advanced configurations like masks etc., because I don’t want to freak out the basic users, to whom the article is intended in first place.
Who is the owner of the file matters as much as the permissions themselves. Here, www-data (or www, or httpd on some system,s or whatever stands for the server) is the bad guy. Actually, the server is the servant: he is a hard working guy, but you don’t want him to have to much power. He’s also quite stupid and easily tricked.
Even very restrictive permissions are useless if the server owns the files. Anyone who can somehow control the server, can potentially change the files to his needs. In shared hosting environments this means that anyone on the same server can change your files using a php script running on his site. It also means, that one compromised script is a threat for all your applications, owned by the server.
The lucky seven and the number of the beast
Everybody knows that 777 means granting all the rights to everyone (on the system). It’s considered as a bad set of permissions. However, few seem to understand what that really means. There are other combinations that are almost just as unsafe as the (un)lucky seven.
Since php scripts are just read by the server who passes them to the executing script (the php interpreter), php scripts themselves do not need the execution bit. That means that in a server context, for a php file, the number of the beast (666) is almost just as unlucky as the lucky seven (777).
Php scripts don’t need the execute byte, so we shall not give them one. Actually, any file (not just php) in the server root that has the execute byte turned on is a threat, because it can easily be transformed into a shell script (which is a real disaster if cgi is turned on).