CiviCRM (and Drupal) issue warnings when a file directory permission presents risk. However, periodic warnings also indicate that a file directory cannot be accessed because of a permission setting. These warnings seem to contradict each other from time to time - recently using an extension.

Are here recommended settings for both ownership and permissions (assuming apache as group setting)? For CiviCRM and Drupal files? Are there guidelines for .htaccess files? (individual forum posts address specific user situations but a more comprehensive guideline would help prevent issues)

  • Thanks Dave T. I'm adding this text in hopes that other folks who are setting up Civi 4.7.X on Drupal 7 see the answers below when they get the warning I did in CiviCRM System Status - sites/default/civicrm/extensions is not writable. Please change your file permissions – Joe McLaughlin Mar 27 '17 at 5:28

What you want

  • You want the webserver to have read-only access to all the files and dirs or the site can't function.

  • You want the webserver to have read-write access to all the files it's expected to manage, e.g. everything under sites/default/files

  • You want the webserver to have read (r) and search (x) access to all directories under your webroot (with the exception of any repository dirs, like any .git repos)

  • You want your developer(s) to have read write access throughout.

  • You want to apply this to a pre-existing install that may have who-knows-what permissions.

  • You'd like the permissions to stay this way; so new files must be created with the same rules.

What you DON'T want

  • You don't want your webserver to have write access to your php files. Otherwise an vulnerability that allows evaluating php can write its own php permanently, becoming a stored attack. I've encountered this (not on a CiviCRM install) and it's not nice. The counter to this argument usually goes "oh but I like the one-click update button my CMS offers me and that requires write access and it's surely more secure for people to be easily able to upgrade their site than to go without security updates". So for less experienced developer/implementers on certain non-Drupal CMSes this might be for you.

  • You don't want the execute bit set on files. Unless you do actually need to execute them from a shell.

  • You don't want any permissions wider than those that are required for the proper functioning of the site. Does every user need access? no. Does your mailman user need access? No. Does another website you run on the same host need access? No. So they shouldn't have access, otherwise a vulnerability in an external package could be exploited to access your site/data.


There are many ways to set up your permissions, users and groups and the best way for you will depend on the number of developers you have and what webserver config you use.

I am a single person developer and so I usually have php (etc) files owned by me, put them in a group the webserver user is in, and deny all other access. I use git, too.

Here's what I do for a reset:

First, ensure your user is in the webserver group. Check with the id command. If you're not in the group:

adduser $USER www-data

If you had to do that you'll need to logout and in again (or do su -l $USER) for it to take effect. Without being in the group some of the commands below will silently fail.

cd /var/www/mysite.com/
# Dirs outside of files dir: 02750, Files: 007.
# Owned by developer $USER and group www-data
find -path ./sites/default/files -prune \
  -o -execdir chown $USER:www-data \{\} \+ \
    \( \
       -type f -execdir chmod 00640 \{\} \+ \
    -o -type d -execdir chmod 02750 \{\} \+ \

# In files: allow rw access.
find ./sites/default/files \
       -type f -execdir chmod 00660 \{\} \+ \
    -o -type d -execdir chmod 02770 \{\} \+ \

# Disallow webserver access to any git repos
find . -name .git -type d -execdir chmod 00700 \{\} \+

Note that the last command might generate errors because there may be existing files that are owned by the webserver user, not you, and so you don't have permission to chmod them. Typically you can ignore those errors; you could add tests in the find command but my commands were long enough so I didn't include those complications.


  1. 00640 means rw for user, read for group.
  2. 02750 means rwx for user, rx for group plus group sticky bit which means that any files created within that directory will have the group ownership of the parent dir. This is really handy for developers because it means if you create a file from the shell then it is given the correct group and the webserver can access it.
  3. 00660 means rw for user and group.
  4. 02770 is like (2) but also gives group write access.

These are the Unix/Linux permissions I tend to set my permissions for CiviCRM directories in Drupal 7:

  • chmod 555 sites/default
  • chmod 644 sites/default/settings.php
  • chmod 644 sites/default/civicrm.settings.php
  • chmod 770 sites/default/files
  • chmod 755 sites/default/files/civicrm

I generally have the ownership set to the hosting account username and the group to the server group, like apache so something like:

  • sudo chown username:daemon -R httpdocs
  • Should these apply to subdirectories? -R where that is the case? Are your public and upload directories covered by these? Thanks – Dave T Mar 29 '15 at 22:44
  • I get this error - CiviCRM does not have permission to write temp files in /var/www/html/sites/default/files/civicrm/templates_c/en_US/, Exiting – Dave T Mar 29 '15 at 23:24
  • chmod -R 775 sites/default/files/civicrm solves the templates_c problem and error on reading latest-version-cache.txt - it seems there should be a better solution than current trial and error. I can help test but someone who knows the code might be able to indicate what permissions are required by each component – Dave T Mar 30 '15 at 0:21
  • When I set up a site on a regular server (hosted or VPS), I don't need to set the settings except for when installing CiviCRM. I set settings.php and sites/default/files to 777 while I install and then set it back to 644 and 770 once I'm done. The Civi installer will set the correct permissions for the stuff in sites/default/files/civicrm. – Andrew Wasson Mar 30 '15 at 17:14
  • When I set up a Drupal/CiviCRM site on a raw server (ie: Ubuntu LAMP) I uncompress Drupal in a directory and set the whole site: /var/www/the-site -to- 770 and then I'll set sites/default and everything inside to 777 for install. The Drupal installer will set the appropriate permissions for everything inside sites/default/files and once I'm done, I have to set sites/default/settings.php to 644 and make sure that sites/default is set to 555 or 550. – Andrew Wasson Mar 30 '15 at 17:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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