Security

Server permissions that stop one bad plugin from taking down the site

If the web server can write to your theme and plugin files, so can an attacker who finds one hole. A simple ownership policy that limits the damage.

A combination padlock resting on a laptop keyboard

Most hacked WordPress sites I’ve cleaned up didn’t fall to a clever attack. A vulnerable plugin let someone upload a file, and because the web server could write almost anywhere, that file ended up everywhere.

The principle: the web server reads, it doesn’t write

Code files, meaning WordPress core, themes and plugins, should be owned by a deploy user, not the web server user. The web server only needs write access to a short list of folders.

# Code owned by the deploy user: the web server can read, not write
chown -R deploy:deploy /var/www/site
find /var/www/site -type d -exec chmod 755 {} \;
find /var/www/site -type f -exec chmod 644 {} \;

# Only the folders WordPress must write to
chown -R deploy:www-data /var/www/site/wp-content/uploads
find /var/www/site/wp-content/uploads -type d -exec chmod 775 {} \;
find /var/www/site/wp-content/uploads -type f -exec chmod 664 {} \;

Which folders need write access

  • wp-content/uploads, for media.
  • Cache folders used by your caching plugin.
  • Log or config folders used by security and firewall plugins.
  • Nothing in themes or plugins.

The trade-off

With locked-down code folders, one-click updates from the dashboard stop working. That’s the point: updates go through your deploy process and get tested on staging first.

Belt and braces

  • Block PHP from running inside the uploads folder at the web server.
  • Make wp-config.php readable only by the users that need it.
  • Schedule a check that ownership hasn’t drifted after manual fixes.

Permissions won’t stop every attack, but they turn “the whole server is compromised” into “one folder needs cleaning.”

Tim Dalbey