File system enforcement of process privileges
File Permissions
Preliminaries
This note describes the checks taken by the server's file system to limit the server's ability to access devices files outside its scope.
The operating system's file system blocks access to files that the server does not have permission to use. When configured correctly, this allows user-agents to directly access resources in the public directory, and indirectly access resources in the dynamic cache, encoding cache, and custom-errors directory.
When improperly configured, bad actors could potentially exploit unknown weaknesses in the server in an attempt to access files outside these well known areas. Conversely, when improperly over-configured the server may not have permission to make legitimate read and write requests.
Document directory
For a typical static web server, the document-root
should have its file permissions set to be read-only, by the system user that is executing the server process. On Linux systems the system user for the server process is typically "rwserve
", and the examples below follow that convention.
A good way to recursively assign read-only permission to all of the directories and files in the public directory is with the find
command. For example, if the public directory for the website is /srv/example.com/document-root
, the correct commands to secure those files for use by the server would be:
cd /srv/example.com
chown -R rwserve:rwserve document-root
find document-root -type d -exec chmod 0750 {} \;
find document-root -type f -exec chmod 0640 {} \;
Cache directories
The encoding-cache
and dynamic-cache
contain files that are created by the server, so those two directories must be both readable and writable by the server process. The correct commands to secure those files for use by the server would be:
cd /srv/example.com
chown -R rwserve:rwserve encoding-cache
find encoding-cache -type d -exec chmod 0770 {} \;
find encoding-cache -type f -exec chmod 0660 {} \;
chown -R rwserve:rwserve dynamic-cache
find dynamic-cache -type d -exec chmod 0770 {} \;
find dynamic-cache -type f -exec chmod 0660 {} \;
Server source code
The server's source code is not "executable", and should be read-only. If the source code is installed at /usr/lib/node_modules/rwserve
, the correct commands to secure it would be:
cd /usr/lib/node_modules
chown -R rwserve:rwserve rwserve
find rwserve -type d -exec chmod 0750 {} \;
find rwserve -type f -exec chmod 0640 {} \;
JaveScript plugin modules
Just like the server's source code, any JavaScript plugins configured for the server should be read-only. If plugins are installed at /srv/plugins
, the correct commands to secure it would be:
chown rwserve:rwserve /srv/plugins/*
chmod 0640 /srv/plugins/*
Configuration files
The configuration files should be readable by the server process. The correct commands to secure them are:
chown rwserve:rwserve /etc/rwserve/*
chmod 0750 /etc/rwserve/*
systemd unit file
The systemd unit file can only be accessed by the root user. The correct commands to secure it are:
chown root:root /usr/lib/systemd/system/rwserve.service
chmod 0640 /usr/lib/systemd/system/rwserve.service
Let's Encrypt certificates
If you use Let's Encrypt certificates, and they are set for renewal using a cron job running as root, the correct commands to secure them are:
cd /etc/letsencrypt
chown -R root:root /etc/letsencrypt
find /etc/letsencrypt -type d -exec chmod 0755 {} \;
find /etc/letsencrypt -type f -exec chmod 0644 {} \;
Review
Key points to remember:
- The owner and group for all files should be
rwserve
. - The website's public documents and the server's source code files should be read-only.
- The server's encoding-cache and dynamic-cache should be readable and writable.