WordPress Security

The title feels like an oxymoron. Out of the box WordPress is horribly insecure but that doesn’t mean that core developers write bad code. Considering the scale of deployment WordPress is actually doing an amazing job. Lets look at what makes sysops frown at the word “WordPress” and what we can do to improve security.

Is WordPress development intimidating?

It definitely should be! WP powers 29% of the visible web. If you develop free or premium themes or plugins you are shouldering a great responsibility. As an open source developer you can breathe a sigh of relief because the license protects you from liability, but that should not be an excuse. It’s up to you to ensure that your code is secure.

Insecure by design

Most security issues stem from the fact that WP caters to non-developers. Simplicity of installation and addon management require the CMS’s files be writable by the PHP process. This is the single worst design decision in WP – to require write permissions on the file system.

Why is this a problem?

Imagine you find a vulnerability in a method that processes some kind of input. If you can write to the file system, you can easily dump a file that would give you complete access to all the data on the server. What most often happens is that exploiters inject a bit of JavaScript into the page which redirects users through a rabbit hole of ads at best or infects their computers with malware at worst.

Unix permissions

Every process and every file on the server is owned by a user and a group. In addition to ownership, files also have permission flags that specify who can do what. You can read all about unix permissions on the Arch wiki.

On many servers the PHP process is configured to run as the www-data user. This user is also part of the www-data group (yes, same name). So if something WP related requires write permissions, that means that the file or directory that needs to be written to, needs to be owned by the www-data user or group. You should never give the other users write permissions e.g. please don’t ever do 777.

Avoiding file permission related security issues

Please note that the following instructions will disable the option to install themes and plugins from within WP. It will also prevent automatic updates. By doing the following you’re committing yourself to manually maintain your installation.

1. Disable automatic updates and file mods (the built-in file editor)

Your clients shouldn’t be touching the website’s code, ever. If there’s an option for somebody to write to some file using the PHP process, then somebody will write to some file using the PHP process. More often than not, it won’t be the good guys. So make sure you define the following constants (in wp-config.php for example):

https://gist.github.com/andrejcremoznik/8d6ecef7aa11b8750a28637b42b57528#file-wp-config.php

2. Set appropriate file ownership and permissions

The only directory that requires write permissions for PHP is uploads. First ensure everything inside your webroot path is owned by a non-root normal user on the server. Then set ownership of uploads to that user and the www-data group. Then give the group write permission with chmod g+w uploads. For example:

https://gist.github.com/andrejcremoznik/8d6ecef7aa11b8750a28637b42b57528#file-file-perms.sh

3. Prevent access to script files inside uploads

Unfortunately, the uploads directory can still be written to by PHP which means somebody will someday put something inappropriate there. It’s possible to prevent access to any script files which may appear there by configuring your web server. For some reason Apache is still popular nowadays, but I don’t use it so you’ll have to port the following Nginx directive to Apache yourself:

https://gist.github.com/andrejcremoznik/8d6ecef7aa11b8750a28637b42b57528#file-nginx.conf

To be continued…

This has gotten too long already. Next time we’ll have a look at WordPress plugin and theme directories and see if it’s possible to evaluate 3rd party code quality. There are also other security measures you can take by avoiding admin accounts and restricting unnecessary functionality. In the end I’ll show you how you can simplify development and maintenance with composer and automated deployment tools.