Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I'm trying to get a better understanding of the potential security holes my default filesystem permissions might be creating. It appears I am capable of traversing my filesystem, serving simple php pages that display info from files outside my /var/www Web Root:

echo file_exists('../../../bin/filename');

I don't know if this capability is normal if the permissions of my Web Root are set properly. I have the permissions of /var/www as 750, where owner:group = root:www-data.

Since my Web Root's parent directories, / and /var, have owner:group = root:root, their permissions need to be 755 because child directories will not be capable of having more permissions than their parents, and the www-data user that apache is running under will fall into its parents' "other" user category. So, it seems like the ability to traverse outside the Web Root might be normal.

Assuming this behaviour is normal, is it a good practice to set directories that are not parents of my Web Root, like /bin, /sbin, etc., with permissions of 750 so www-data in this case can't get to them?

share|improve this question

2 Answers 2

up vote 0 down vote accepted

In terms of restricting what a webserver can do - I usually grant access to the content by the webserver via the 'other' entity (rw-rw-r-- / drwxrwsr-x) - this allows me to set up a group (in some cases multiple groups) of people who can maintain (write) the files. On a simple machine it also means I can strip execute and read permissions elsewhere minimal impact. But using chroot (or containers) is a more effective solution where applicable.

Your example code seem to be using PHP: disabling allow_url_include and setting open_basedir are essential first steps in hardening a server (there's lots more - but this is straying off-topic). Setting open_basedir prevents nearly all directory traversal mechanisms. But the really important thing is to not process paths supplied from the web unless you you cannot avoid the issue - and even then thoroughly validate the data using a whitelist and realpath().

share|improve this answer

In order to access a file or directory, you have to have execute access to its parent directory (and therefore all parents above it).

Therefore, if I can access '/var/www/html', then I implicitly can also access /var/www/ and /var and /. That doesn't mean I can do much with it, though, because my to any other subtree is determined by the permission on that directory.

So while while I can get to /var/www/html, that doesn't mean that I can get to /var/www/docs -- it depends on the permissions on docs.

Now, here's the important detail for file permissions, and once you understand this, you can craft a reasonable permissions set:

For Files

  • read: Means you have access to open the file read-only and access its contents
  • write: Means you have access to open an existing file read-write and modify or delete its contents. It doesn't mean you can delete the file entry, but you can truncate the file to empty, or change it to say something else.
  • execute: means you have permission to run the file. You may not see its contents because the OS will read the file on your behalf and execute it for you.

For Directories

  • read: means you have access to list the files in a directory. You may not have access to do anything with them, but you can at least see their names, sizes, permissions, etc.
  • write: means you have access to change the list of files in a directory. That is, you can create files, delete them, rename them, etc. You may not be able to open (read or write) any existing files, but you can modify the list.
  • execute: means you can access the files or directories instead the directory as long as you know the name and have the appropriate permissions on the child file or dir. You can use the directory, but you don't have permission to modify or see the list of files.

So to access a given child directory, all you need is the execute bit. So on /home/ for example, it's not uncommon to see the permissions set to rwx--x--x and owned by root, with users directories set to rwx------ and owned by the user. This gives each user access to his own directory, but he can't access or even list the other directories under /home.

Even better

An even better system, which is still in development but is stable enough for early adopters, is to use Linux cgroups to give each user or site or program its own filesystem entirely. This is done using a combination of chroot and mount --bind and often unionizing filesystems (like unionfs or aufs) to give each process access to only the files it needs, without unnecessary duplication.

Furthermore, cgroups allow individual processes to live on isolated networks with isolate memory and socket domains and similar resources. This creates the potential for what looks and acts a lot like a virtual machine, but without the virtual machine. This technology is still advancing, but it's pretty clear that this is going to be the way forward for process isolation in Linux.

Relevant projects using this technology include LXC and Docker, offers a very user-friendly way of setting up isolated containers which include their whole "world" from an execution perspective (much like a VM), but without adding virtualization overhead.

share|improve this answer
So is it reasonable/common/prudent to remove all permissions for the user that apache is running under on all subtrees (that apache does not need to operate) branching from the Web Root's parent hierarchy, whether a chroot configuration of some sort is implemented or not? This would seem to follow the security principle, Principle of Least Privilege. –  Kevin Feb 23 at 0:55
@Kevin It's reasonable and prudent to remove all unnecessary permissions, whatever that may mean in your context. Different software in different environments has different requirements, so I can't give any specific advice. –  tylerl Feb 23 at 2:07
tylerl, I like your answer. Would you ever suggest using SELinux? By default in Centos/Fedora it seems to restrict the httpd from accessing anything outside of /var/www –  CtrlDot Feb 24 at 18:55
@CtrlDot SELinux adds more granularity for permissions. So if that's useful to you, then use that. –  tylerl Feb 24 at 21:22

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.