by James Sansbury on July 20, 2011 // Short URL

Keeping Drupal's Files Safe

The Black Art of File Permissions

When Drupal users deploy their first (or second, or tenth...) site to a real web server, one of the most common points of confusion is the proper access permissions for the files directory and settings.php. Because the files directory stores uploaded content from the site's users, badly configured permissions are a potential security risk. Lock it down too tightly, though, and managing backups or future migrations can be a pain.

My standard starting point when creating a new Drupal site on a server is to create or select an existing user that is a part of the web server group (typically the Apache group), and give ownership of all Drupal files to that user. On Ubuntu, these are the commands to get that set up:

(
  # Create a new example user.
  useradd -s /bin/bash -m example;

  # Now add that user to the Apache group. On Ubuntu/Debian this group is usually
  # called www-data, on CentOS it's usually apache.
  usermod -a -G www-data example;

  # Set up a password for this user.
  passwd example;
)

Once I have that set up, I'll log in as the user and install Drupal at /var/www/example/docroot or a similar path, then create the files directory by hand and copy over the settings.php file. Since we log in as our example user before copying in Drupal, our file ownership and permissions should automatically be properly configured on all the core Drupal files and scripts (including .htaccess files).

su - example
cd docroot
cp sites/default/default.settings.php sites/default/settings.php

# Temporarily give the web server write permissions to settings.php
chgrp www-data sites/default/settings.php
chmod g+w sites/default/settings.php

Now let's set up the files directory.

# Create the directory.
mkdir sites/default/files

# Now set the group to the Apache group. -R means recursive, and -v means
# verbose mode.
chgrp -Rv www-data sites/default/files

Next we'll set up permissions so that the web server can always write to any file that is in this directory. We do this by using 2775 in our chmod command. The 2 means that the group id will be preserved for any new files created in this directory. What that means is that www--data will always be the group on any files, thereby ensuring that web server and the user will both always have write permissions to any new files that are placed in this directory. The first 7 means that the owner (example) can R (Read) W (Write) and X (Execute) any files in here. The second 7 means that group (www-data) can also R W and X any files in this directory. Finally, the 5 means that other users can R and X files, but not write.

chmod 2775 sites/default/files

If there are any existing files in this directory, be sure the web server has write perms on them.

chmod g+w -R sites/default/files

Now Drupal is ready to be installed. When finished, it is VERY important to come back to settings.php and ensure that all users only have read permissions.

chmod 444 sites/default/settings.php

That's it! This set up will keep uploaded files from being executed and settings.php from being accessed improperly, and sidestep annoying lockouts that prevent you from writing, changing, or removing user-uploaded files.

James Sansbury

Development Manager

Want James Sansbury to speak at your event? Contact us with the details and we’ll be in touch soon.

Comments

Anonymous

Great Post! Quick question

Great Post!

Quick question though... once the site is running and I want to verify the permissions... what settings do you need for files and folders inside sites/default/files?

In other words, would applying these settings cause issues to a site that has already been running in regard to Imagecache and such?

Reply

q0rban

If you have existing files in

If you have existing files in your files directory, you can still run all these commands without fear of damaging anything. In fact, I'll often log into existing sites, notice incorrect file permissions, and do this very thing:

// Ensure owner/group is correct
chown -Rv example.www-data files
// Set up proper permissions on the parent directory
chmod 2775 files
// Ensure group has write permissions for all files.
chmod -Rv g+w files
Reply

Gloria Rom

The files and directories

The files and directories below the directory named "files" don't need to be homogeneous. For example, most files won't need to be executable by anybody, while most directories will need to be executable by everybody.

As for your question about the effect of chmod g+w on a file with 777 permissions (ugo=rwx), the answer is that the command has no effect, but don't take my word for it. Try it yourself on some test files.

Reply

DjebbZ

Nice to know !

Thanks for the reminder. I didn't know about the 2 option in chmod, very useful !

Reply

Christopher Pelham

but but... :)

That is clear and helpful but Drupal is supposed to be deployable and usable -- safely! -- by the masses without touching (or even knowing about) the command line, so is there a way to have Drupal do this automatically on install?

Reply

q0rban

If you install Drupal using

If you install Drupal using the built in installer and it is able to create the files directory for you, the permissions are set up securely (or it notifies you if they aren't). In some ways these instructions are primarily for people who must do it on their own, or for drush users who are tired of seeing "permission denied" errors when they try to clear their cache. :)

Reply

Tor Arne Thune

Great solution for Drushers

This is a great solution for anyone installing sites with Drush, having to type sudo -u www-data in front of every Drush command (or using su - www-data) that modifies files in the files directory. Drush clears/creates (cache clearing) different files in the files directory when installing or upgrading, and it's a pain to have to remember to sudo -u www-data all the time, and as a side effect being unable to modify any files in the Drupal directory as the every-day user without typing the same sudo -u www-data in front of everything.

Of course in my case I will add my normal every-day user to the www-data group, skipping the step of having to create a new user and use su - newuser. Do you see any problems with this approach?

Thanks! This will definitely make my life easier.

Reply

q0rban

Of course in my case I will

Of course in my case I will add my normal every-day user to the www-data group, skipping the step of having to create a new user and use su - newuser. Do you see any problems with this approach?

As long as you're comfortable with that user being a part of the www-data group, that's not a problem. :)

Reply

Kartagis

Semicolon

Hi,

In the first example, I noticed there were semicolons at the end of commands. They are not supposed to be there.

Reply

q0rban

Actually correct

Hi there! Thanks for pointing that out, as it might be confusing. Those commands are all wrapped in parentheses so that someone could just copy and paste the whole set of commands and run them. That's why the semicolons are necessary. If you just want to copy a single line, the semicolons don't break anything either. :)

Reply

nicl

great article, how does this work dev -> staging -> production?

Hey, thanks for the brilliant article. Very straightforward to understand. Feel like this should be added to D.0 asap (the current doc pages there about permissions are much harder to understand/apply in my view).

One question: how do you apply this to the dev->staging->production process?

Do you repeat the process for each new server? Or do the user/group settings get carried over (I don't know how this works) and you just recreate the user for each stack?

Hope that makes sense,

nicl (my d.o username)

Reply

q0rban

One question: how do you

One question: how do you apply this to the dev->staging->production process?

Do you repeat the process for each new server? Or do the user/group settings get carried over (I don't know how this works) and you just recreate the user for each stack?

Great question!

I would say most often that you repeat the process on every server, however I suppose if you were actually committing your files directory and settings.php to git version control, you could rely on that to deploy your changes to file permissions.

Reply

Anonymous

Status report message

I typed chmod -R 2775 files and get message from
Status report :
CTools
"CSS Cache Unable to create
The CTools CSS cache directory, ctools/css could not be created due to a misconfigured files directory. Please ensure that the files directory is correctly configured and that the webserver has permission to create directories."
and also
File system
"Writable (public download method)
The directory sites/default/files is not writable. You may need to set the correct directory at the file system settings page or change the current directory's permissions so that it is writable."

Reply

Anonymous

add to above

Some how File systems
"Public file system path" is set
sites/default/files and its unable to change from File system.
Default download method is cheked to
"Public local files served by the webserver"

And Ctools CSS ...?

Reply

q0rban

Be sure you follow the

Be sure you follow the instructions carefully. You need to first ensure that the group assignment is correct, and also the command you need to run there should not have -R in it. If you're still having problems, it sounds like the Apache group is configured incorrectly.

Reply

Anonymous

Apache group

Is there posibile to check out configured Apache gruop via drush

Reply

Amkus

About group

# Now add that user to the Apache group. On Ubuntu/Debian this group is usually
# called www-data, on CentOS it's usually apache.
usermod -a -G www-data example;

What would this group be in MacOs? And are those commands
working with drush?

Reply

j2b

Should it be really 2775

Hi, really thanks for short and easy to read article, but I have been studying this issue from time to time, and there's the fact, that I've understood from other forums say, that in no way web server user (and process) has to have write access to website code files, or the other - it is not to be considered as a secured deployment. The best security measure says, that web server can access files for read and execute via group or "other" parameters. It is even stated in this article: http://drupal.org/node/244924.

There are some issues with sites/default/files directory, as web server has to do its job, but as I've understood before, this is the only place, where some manual changes should be done. Another question on this is Private files upload state.

My notice was, that in most cases 755, where web server is only in common group with a user, Drupal works, except some modules. And this situation gives full ownership and access to files to work for developer, and is enough for Drupal. (of course sites/default/files in such case should be changed to 775, where web server is in the same group as user). Can you comment on this?

Reply

q0rban

2775 for files directory only

Yes, you don't want the webserver to be able to write to any directory but the files directory, and as you can see in the instructions above, that is the only directory we are giving write permissions to.

I hope this clarifies. :)

Reply

j2b

Yes. I somehow missed the

Yes. I somehow missed the point, that article is only about sites/default/files directory and was (wrongly) relating it to whole Drupal installation directory.

Reply

Jutendra

Thanks for the help

I've been working on a web project using Drupal for the past 2 weeks. My team is developing an interactive applicant tracking software package to the corporate website. Usually an easy task, but we were struggling with the separate permissions needed for the various files. This was a huge help, we got things loaded over the weekend and testing today. Thanks again!

Reply