Skip to main content

Secure web server permissions that just work

I have been doing web development since, well, web development basically began. And I've used a wide range of hosts. Since I don't see anyone stating answers succinctly and definitively anywhere, it is time to write a solution to the question on everyone's mind: What are the permissions that I should set for web server directories and files?

The first step is to identify the user that the web server will access files with/run under. For example, many Linux distributions set up 'www-data' as the user. I'll be focusing mostly on Linux as it powers about 66% of the Interwebs, but Windows Server users can benefit too.

It is important to get your setup correct from the very beginning. Propagating permissions down the website tree as new directories and files are created is critical to maintaining sanity. Knowing who created a specific file or directory is also important when working in a team. As always, if you can't trust other users who might have access to the files on the system, then you should not be using that system. This is especially true of shared hosting and so you need a VPS, cloud, or a dedicated host if you want to do web server operations correctly and securely.

Going back to the example for Linux, this is the best solution I've come up with that minimizes the number of times ownership has to be adjusted by an admin/sudo/root user:
  • Create a new group (e.g. 'addgroup sftp-users' on Debian/Ubuntu).
  • Add users to the group who will be allowed to upload files to the web server via SFTP (e.g. 'adduser youruser sftp-users' on Debian/Ubuntu). No one should be using FTP anymore.
  • Create a directory for the web server files (e.g. 'mkdir /var/www').
  • Adjust permissions (e.g. 'chown root /var/www', 'chgrp sftp-users /var/www', 'chmod 775 /var/www', and 'chmod g+s /var/www').
  • Create a directory for cron/scheduled custom scripts to run (e.g. 'mkdir /var/scripts').
  • Adjust permissions (e.g. 'chown root /var/scripts', 'chgrp sftp-users /var/scripts', 'chmod 770 /var/scripts', and 'chmod g+s /var/scripts').
If the web server use needs to be able to write to a specific directory within the tree structure, it should, first and foremost, be its own isolated directory (e.g. 'uploads'). Then change ownership to the web server user (e.g. 'chown www-data uploads'). I've never had a legitimate need to set 'chmod 777' on a directory or file with this approach.

The 'g+s' sets the sticky bit for the group, which propagates the group AND the permissions down the tree as new files and directories are created. This allows all users in the group to freely edit those files and create new directories without having to constantly use the command-line to adjust ownership.

Putting 'cron' scripts in the web root is just asking for trouble unless you carefully restrict each script to only run from the command-line (it can be accomplished though). It's just easier to have a separate directory that's outside the web server's document root for executable code that cron or custom services that the OS runs (e.g. Cloud Storage Server /scripts).

Alrighty, that's about all on this topic. And now you know!

Comments