Improving WordPress security

Security is often largely undervalued and misunderstood when maintaining a website. Good security not only prevents attacks which do invetibly occur, but minimises risk so that the impact of a successful attack is low.

In light of recent attacks on some of the WordPress sites I work on, I revisited Chris Shiflett’s highly rated Essential PHP Security and Hardening WordPressx. The following are a few of the lessons I learned.

Moving WordPress into a subdirectory

The purpose of moving WordPress into a subdirectory is to prevent intruders from injecting malicious code into core WordPress files. In the default configuration, these files would be in the root directory but in custom-named subdirectory they’re harder to find. To migrate an existing site, I moved all its files into the subdirectory, including its .htaccess file. Then I put the following in an .htaccess file at the root.

    <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteCond %{HTTP_HOST} ^(www.)?$
        RewriteCond %{REQUEST_URI} !^/subdirectory/
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ /subdirectory/$1
        RewriteCond %{HTTP_HOST} ^(www.)?$
        RewriteRule ^(/)?$ subdirectory/index.php [L]


Preventing execution of PHP code from the uploads directory

Putting an .htaccess file in the uploads directory containing the following prevents PHP code from being executed there, should files ever be uploaded there.

    <Files *.php>
        deny from all


Determining wp-config’s access

The following determines who can access our wp-config file.

    <Files subdirectory/wp-config.php>
        order allow,deny
        deny from all


Changing .htaccess permissions

Changing our .htaccess file’s permissions to 770 with the following command ensures it can be read, written to and executed by its group but not publicly.

    chmod 770 .htaccess


Preventing theme files from being edited in WordPress’ admin

Defining the below constant in our wp-config file prevents files from being edited through the admin dashboard. This would reduce escalation should an intruder gain unauthorised access to the admin interface.

    * Prevents users from editing WP files from the dashboard.
    define('DISALLOW_FILE_EDIT', true);