Security HowTo's

Secure WordPress the Hardcore Way

I’ve written about wordpress plenty of times and this time is on how to secure a wordpress installation. Specifically, i have been responsible for a few sites that’ve recently been hacked. Essentially the “bad guys” found a way to upload some files onto the sites and then execute php scripts to extract ZIP file contents and turn the site into spam cannons.

Most of the wordpress installs i look after are hosted on Apache. All of what i’m talking about in this article applies to any web-server but obviously you’d have to apply these changes in different ways. Also i’m working on a CentOS server in this example but there’s only a few little differences that i’m sure you can accommodate on Debian style servers. One last thing to keep in mind is that my wordpress install in this example is in “/var/www/html” but normally you’d put it a little deeper such as “/var/www/html/www.example.com/wordpress/”.

Here’s how it goes: a) Someone calls and says “our sites been hacked”. b) I confirm it and take a backup for prosperity. c) I restore from backups or get the original developer to re-deploy the site. I set the permissions to no-writes and make the owner of the wordpress files “root”. At this point no wordpress code-base (or more likely one of the plugins) still contains the flaw(s) that was used in the original exploit so nothing can be left to chance. d) I harden the web-site rules to limit access to POST commands and sometimes to the /wp-admin directory. e) Finally i correct the permissions and ownership to allow updates to run but i keep them as restricted as possible. f) And run the updates. g) At this point we should be good but a little monitoring is key here so consider both using Tripwire and monitoring the logs.

Follow along to take steps to harden your wordpress site installation.

The first thing to do is make sure you have a schedule for running updates for the wordpress code and plugins as well as the web server and operating system.

In my experience the database is rarely/never touched and it’s the code that’s effected. But take backups of both daily just in case. Notice i put the password in the command which isn’t great for security so consider an alternative method in this article “http://stackoverflow.com/questions/148951/does-mysqldump-password-really-do-what-it-says”. And yes, i realise that if someone does have the ability to execute arbitrary PHP commands on your server, they also can list the contents of the “wp-config.php” file and see the database password.

Backup MySQL:

mysqldump -u myUser password=myPassword wordpress-db > /media/backups/wordpress/daily-backup-mysql-$(date +"%m-%d-%Y").sql

Backup the WordPress code:

tar -czf /media/backups/wordpress/daily-backup-code-$(date +"%m-%d-%Y").tgz /var/www/html /etc/httpd /var/log/httpd

Set permissions on the wordpress installation to be as restrictive as possible. The sad part is that wordpress ‘needs’ the ability to write to its self for updates and image uploads, etc. But we can at least limit that a little.

TIP: the following assumes the location of your web directory. Correct it before applying.

cd /var/www/html
chown apache.apache -R ./
find -type d ./ | xargs chmod 770
find -type f ./ | xargs chmod 660

Add the following to lines to your “/var/www/html/wp-config.php” file to allow automatic wordpress updates.

define( 'WP_AUTO_UPDATE_CORE', true );
define( 'AUTOMATIC_UPDATER_DISABLED', false );

Add the following to the top of your “/var/www/html/.htaccess” file. It ensures no one can post (with the POST “method”) to your site except those coming from either “127.0.0.1” or “1.2.3.4” of anyone from the private networks (192.168.x.x, 10.x.x.x, 172.16.x.x). That includes logging in, sending arbitrary rubbish to scripts and posting new articles and pages. Add ip addresses and/or ranges as you like. Your IP address will need to be added if you want to write blog articles or change other content on your wordpress site.

Add the following to your Apache vhost configuration file. It will block all access to your “xmlrpc.php” file:


 Order Deny,Allow
 Deny From all

Keep in mind that this would also stop visitors from commenting on your articles and submitting contact forms. You’d need to have exclusions for such things not documented here.

<IfModule mod_rewrite.c>
 RewriteCond %{REQUEST_METHOD} POST
 RewriteCond %{REMOTE_ADDR} !127.0.0.1
 RewriteCond %{REMOTE_ADDR} !1.2.3.4
 RewriteCond %{REMOTE_ADDR} !192.168.
 RewriteCond %{REMOTE_ADDR} !10.
 RewriteCond %{REMOTE_ADDR} !172.16.
 RewriteRule .* - [F,L]
</IfModule>

Finally you need to monitor your wordpress site for issues. You’ll also learn how the bad guys are trying to compromise your site. Use two methods for this. a) monitor the logs, and b) use Tripwire to show which files are changed on the server in recent times.

Monitor your logs with the “tail” command like this:

tail -f /var/log/http/wordpress.log

Read about Tripwire in a recent article:

http://www.agix.com.au/tripwire-centos-7/

At this point your site should be in great shape and remain that way.

Similar Posts:

Leave a Reply

Your email address will not be published. Required fields are marked *