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.
How
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.
Explanation
00640
means rw for user, read for group.
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.
00660
means rw for user and group.
02770
is like (2) but also gives group write access.