Securing file permissions and ownership

Last modified: November 19, 2009 - 18:10

The server file system should be configured so that the webserver (e.g. Apache) does not have permission to edit or write the files which it then executes. That is, all of your files should be 'read only' for the Apache process, and owned with write permissions by a separate user.

Configuration examples

For example, on many systems the Apache process runs as a user called "www-data". This user should be able to read all of the files in your Drupal directory either by group permissions or by "other" permissions. It should not have write permissions to the code in your Drupal directory. If you use features of Drupal which require the "files" directory, then give the www-data user the permission to write files only in that directory.

Following is an example file listing of a safe configuration showing two files in a site where uploaded files are stored in the "files" directory. In order to see the file permissions set for your set-up, go to the command line and type: ls -al.

drwxrwx--- 7 www-data greg 4096 2008-01-18 11:02 files/
drwxr-x--- 32 greg www-data  4096 2008-01-18 11:48 modules/
-rw-r----- 1 greg www-data 873 2007-11-13 15:35 index.php

In the above example, the web server user has the ability to write in the files directory, any users in the group "greg" can read and write the data as well, but other users are not allowed to interact with that data. The "index.php" file (representative of all code files) can be edited by members of the group "greg" and can be read by the www-data group (we assume the www-data user is in the www-data group). No other users can read that file. This is a fairly secure method of configuring your site. You generally don't want random users who have the ability to read files on your server to see inside those files, hence the last three permissions are --- instead of r-x.

Below is an insecure setup:

drwxrwx--- 32 greg www-data  4096 2008-05-16 11:48 modules
drwxrwx--- 7 www-data www-data 4096 2008-01-18 11:02 files/
-rw-rw-rw- 1 www-data www-data 873 2007-11-13 15:35 index.php
NOTE: THIS IS AN INSECURE CONFIGURATION

This configuration allows the www-data user to edit the index.php file (and since it is representative of other files, we assume every file that makes up the Drupal site). This configuration is dangerous for the reasons outlined below. If you are using a configuration like this, please change it immediately to be more like the first version.

Quick Lesson in Permission's Numeric Equivalents

Special numbers mean less than "read write execute".
In general, special numbers like "4 means read, 2 means write, and 1 means execute" are less useful than "r means read, w means write, and x means execute."

However, some folks/software need numbers so:

rwxrwx--- is also 770

How insecure permissions are a problem

If you allow your site to modify the files which form the code running your site, you make it much easier for someone to take over your server.

Worst case scenario: a file upload tool in Drupal allows users to upload a file with any name and any contents. This allows a user to upload a mail relay PHP script to your site, which they can place wherever they want to turn your server into a machine to forward unsolicited commercial email. This script could also be used to read every email address out of your database, or other personal information.

Undesirable scenario: if the malicious user can upload a file with any name but not control the contents, then they could easily upload a file which overwrites your index.php (or another critical file) and breaks your site.

Undesirable scenario: if the code allows users to see the contents of files, attackers could see information which might reveal potential attack vectors.

If you are a sysadmin

Linux servers

To set the permissions all at once you can issue these commands from the Drupal root directory. I'm assuming that greg user is part of greg group and that greg is the site owner. (If you do this outside Drupal's root directory you'll mess up all your filesystem's permissions)

[root@localhost]cd /path_to_drupal_installation
[root@localhost]chown greg:www-data * -R
[root@localhost]find . -type d -exec chmod u=rwx,g=rx,o= {} \;
[root@localhost]find . -type f -exec chmod u=rw,g=r,o= {} \;

The second command will give ownership recursively on Drupal's root directory for user greg and www-data group.

The third command will find all directories and subdirectories on Drupal's root directory and execute a chmod that will change the permissions to read, write and access for user greg, read only and access to www-data group and none to others.

The fourth command will find all files inside Drupal's directories and execute a chmod that will change the permissions to read, write for the user greg, read only for www-data group and none to others

Now for the "files" directories the permissions are slightly different because it must have write permission to the www-data group too:

find . -type d -name files -exec chmod ug=rwx,o= {} \;

This command will give read, write and access for user greg and for www-data group and and none to others for all "files" directories inside Drupal's installation directory.

Remember that any newly installed module/theme or whatever addon must have its permissions changed too, It's better to do this BEFORE installing it in its appropriate Drupal directory.

Windows servers

By default, Apache runs in the built in SYSTEM account. So all you have to do is change the permission in a way that only the SYSTEM account, the administrators group and the user greg have access to the Drupal root directory, subdirectories and files (assuming greg is the site owner).

You should exclude all other users and groups from the ACL. For the SYSTEM account give read only access to all Drupal directories, sudirectories and files except for the "files" directories which require write permission. For the user greg give read, modify and write permissions. And for the administrators group give complete access. Go to the Drupal root directory, right click on it, go to properties and then security.

Make use of permission inheritance to make things easier for yourself. And remember that any newly installed module/theme or addon must have its permissions changed too. It's better to do this BEFORE installing it in its appropriate Drupal directory. For those who use permission inheritance it's done automatically by Windows.

re: find . -type d -name

Mike_Waters - May 7, 2009 - 01:36

re: find . -type d -name files -exec chmod ug+rwx,o-rwx {} \;

This only works for a new site (e.g. one that doesn't already have files in the /sites/[site]/files directory).
For the hardening of an existing site,`find . -type f -exec chmod u+r-wx,g+rw-x,o-rwx {} \;` sets all of the files inside sites/[site]/files to be read-only, and `find . -type d -name files -exec chmod ug+rwx,o-rwx {} \;` will only affect new files; anything currently existing in the /files folder will still be read-only. A `chmod -R ug+rwx,o-rwx /[path to site]/files/*` should fix this.

Thanks for the howto.

I think there may be a problem with your recommended fix

ridgerunner - November 3, 2009 - 16:16

chmod -R ug+rwx,o-rwx /[path to site]/files/*

This command gives execute permissions for both the owner and group to all regular files residing within the /[path to site]/files/* tree? Isn't this a bad thing?

No

kokamomi - June 9, 2009 - 19:46

It's nuts that web server should own the site. In all normal cases your regular user (that you do your regular ssh, scp or ftp access with) should should own the installation files.

Anyway, this regular user should normally own an html area exclusively, from which the web server serves the pages of the host/virtualhost, that is only readable and searchable to others (i.e. the web server). After ensuring that this is the case the user then normally copies or uploads the contents of the distribution into the html area, thus maintaining ownership and sane permissions. The user then grant the web server read, write and search permission to the files directory of the site by changing the group access. Optionally, the user also gives up his own write permissions for the files directory (in order not to tamper recklessly with this area as it should be managed exclusively by the web server).

There's really no need for recipes, if the user doesn't grasp this he simply needs to do UNIX permission homework or else he'll never be secure. If that is the case, enter the following into shell or Google:

man chown
man chgrp
man chmod

Thanks for the advice. After

Mike_Waters - June 23, 2009 - 14:39

Thanks for the advice. After reading your post, I found the following relevant information:
http://www.onlamp.com/pub/a/apache/2004/05/28/apacheckbk.html

"Apache runs as the user specified in the User directive. Files need to be readable by that user. Directories need to be +x (searchable) by that user. CGI programs need to be runnable (+x) by that user."

A question

lsrzj - July 16, 2009 - 13:43

User apache is completely unpriviledged and has no login shell. A question, supposing that the file index.php in drupal's root have these file permissions: -r--r----- 1 apache apache 980 Mai 18 15:25 index.php. Would it be possible to an attacker explore an Apache vunerability to take advantage of the ownership by apache to execute a chmod on it and alter the permission in a way that it becomes writeable and then modify or overwrite it uploading a hacked one?

lsrzj, In your case you'll

zanoman - July 22, 2009 - 08:26

lsrzj,

In your case you'll have a useless drupal install since index.php won't be executable :)
AFAIK, if user "apache" has no login shell privileges it cannot chmod (bash won't be available for this user).

It works

lsrzj - August 4, 2009 - 16:12

It won't be a useless Drupal install because it works, that's the way I'm currently running it. If you need the php file to be executable it means that you have a problem with your Apache configuration. If you are needing php files to be executable it's likely that your apache is executing the external php executable and not the internal php interpreter.

Shell or no shell

kokamomi - August 20, 2009 - 19:47

Shell or no shell, as long as the user the server and the php scripts runs as owns files and directories, it can also alter them. Owning files is a privilege. So if your server, or php, or Drupal has a hole, or most likely, if you accidentally allow someone to plant some php code, you're in trouble.

$ ls -l secretfile
---------- 1 www-data www-data 0 2009-08-20 21:10 secretfile
$ wget http://localhost/malign.php > /dev/null 2>&1
$ ls -l secretfile
-rwxrwxrwx 1 www-data www-data 0 2009-08-20 21:10 secretfile

Understood

lsrzj - August 25, 2009 - 13:35

Thank you for your clarification, when you told about this on the comment I became worried because I didn't think of this possibility. Now that you explained how it can be achieved I saw the problem and modified all my permissions in the server to u=rwx,g=rx,o= for directories and u=rw,g=r,o= for files and the ownership is site_owner:apache. This way only site_owner can chmod the files and directories.

doesn't work

kudak - October 25, 2009 - 21:21

Hi, permissions above look pretty tight. However it doesn't work ... at least for me (Ubuntu 8.04 x64 serv), I don't know which files have to be writable, executable etc ... but with these permissions I am getting only "Forbidden - u don't have permissions ....." to whole drupal subdirectory, when I set drupal directories to "chmod 1755" and files "chmod 1644" it's much better (perhaps sticky bit is not necessary), i can work in any case at it's very important for me (newbie in drupal). I would like to have secure site at the same time, therefore I tried permissions here from "wiki", i have experimented with them about 2 hours and ended up with working ones as I mentioned above. I haven't tried to edit .htaccess, perhaps there is also some possiblility to achieve usefull behavior.

----edit-----
as mike_waters points out directories need to be executable (x) so one has to # find . -type d -exec chmod u=rwx,g=rx,o=x {} \; this fix the problem, I should have read carefully his post. It could save me 3 hours of trying and googling ...

ACL Support

elizabethcb - November 17, 2009 - 17:48

ACLs are an under-used feature of Linux. It's great for web development, as the server can have one set of permissions while the developers have their own. However, I don't think Drupal supports this, because it thinks that the server has write permissions to a directory that it doesn't have write permissions to.

Being brand new to Drupal, I could be wrong, but I believe I'm interpreting the example below correctly.

Status Report:
Configuration file Not protected
The directory sites/default is not protected from modifications and poses a security risk. You must change the directory's permissions to be non-writable.

Directory Permissions:
elizabeth:/home/www/faba3.v.cryptomeme.com/webroot/sites$ ll
total 8.0K
drwxrwx---+ 2 elizabeth staff 4.0K 2009-09-16 12:40 all
drwxrwx---+ 3 elizabeth staff 4.0K 2009-11-17 15:27 default

elizabeth:/home/www/faba3.v.cryptomeme.com/webroot/sites$ getfacl default/
# file: default/
# owner: elizabeth
# group: staff
user::rwx
group::rwx
group:www-data:r-x
mask::rwx
other::---
default:user::rwx
default:group::rwx
default:group:www-data:r-x
default:mask::rwx
default:other::---

elizabeth:/home/www/webroot/sites/default$ ll
total 28K
-rw-rw----+ 1 elizabeth elizabeth 9.3K 2009-11-17 15:27 default.settings.php
drwxrwx---+ 2 elizabeth staff     4.0K 2009-11-17 15:26 files
-r--r-----+ 1 elizabeth staff     9.3K 2009-11-17 15:27 settings.php

elizabeth:/home/www/webroot/sites/default$ getfacl files/
# file: files/
# owner: elizabeth
# group: staff
user::rwx
group::rwx
group:www-data:r-x
mask::rwx
other::---
default:user::rwx
default:group::rwx
default:group:www-data:r-x
default:mask::rwx
default:other::---

 
 

Drupal is a registered trademark of Dries Buytaert.