Run Apache workers as an unprivileged user
apache2.conf / httpd.confUser www-data # Debian, UbuntuGroup www-data# User apache # RHEL, Rocky, AlmaDistribution packages already do this. The page matters for hand-built installs,
containers, and configs where someone set User root to fix a permissions error.
Why it matters
Section titled “Why it matters”Apache runs as two kinds of process, and only one should concern you:
- The parent starts as root. It has to: binding ports below 1024 requires privilege, as does reading a properly locked-down TLS private key. It handles no requests.
- The children parse requests, terminate TLS and run your application. They
drop to the configured
User.
So one root line in ps is normal. Every other root line is the finding.
The children are where the risk lives. Apache 2.4.68 fixed thirteen CVEs including
use-after-free and heap overflow conditions — all in request-handling code, all
child-side. Whether such a bug is a contained compromise or a root shell is decided
entirely by the User directive.
The document root should not be writable by the web user
Section titled “The document root should not be writable by the web user”This is the part people skip, and it matters more than the User line on most
servers, because the User line is usually already right.
If www-data can write to the directory it serves, then any file-upload
bug, any path traversal, any vulnerable CMS plugin can drop a .php file into the
web root — and Apache will happily execute it. That’s a web shell from a bug that
would otherwise be a nuisance.
sudo chown -R root:www-data /var/www/htmlsudo find /var/www/html -type d -exec chmod 750 {} +sudo find /var/www/html -type f -exec chmod 640 {} +
# Only the directories that genuinely need writes:sudo chown -R www-data:www-data /var/www/html/uploadssudo chmod 750 /var/www/html/uploadsServe-only, don’t-write is the default you want; carve out the exceptions.
And for the upload directory that must be writable, stop it executing anything:
<Directory /var/www/html/uploads> Options -ExecCGI php_admin_flag engine off AddType text/plain .php .phtml .php5 .phar</Directory>That combination means a .php dropped there is served as plain text, not run.
The private key should not be readable by the workers
Section titled “The private key should not be readable by the workers”The parent reads SSLCertificateKeyFile at startup while still root, so it
does not need to be readable by www-data — and it shouldn’t be:
sudo chown root:root /etc/ssl/private/site.keysudo chmod 600 /etc/ssl/private/site.keyA key readable by the worker user is a key readable by anything that compromises a worker.
Related
Section titled “Related”- Disable unused modules — mod_cgi runs as this user.
- The Apache path traversal — what a worker can read matters once a path bug exists.