WordPress Security

WordPress became very popular with the ever growing number of blogs. People started creating all sorts of guides and tutorials for WordPress itself. But little has been talked about security, even though it is such an important topic. For that reason I wanted to step forward and create a comprehensive WordPress security guide.
Really, there is no reason not to follow along this guide and make your blog more secure. Think of how much it would cost you if your blog were to be hacked?

Before starting with this guide I ask you to back up your blog. Because we will fiddle with the blog it is always useful to have a backup in case something goes wrong.

Alright, now we are set. Let’s hop on to the first topic.

1. Basic Optimization

These are some tips and tricks that have a big impact on your blog’s security. Most of these tricks are very basic and therefore easy to follow.

1.1 Back up Often

Backing up is essential with every web site. Without backing up you have no way of getting back all your data when a server crashes. It is therefore important to backup your blog every so often.

You can either manually or automatically back up. I actually prefer to automatically backup data  because that way you never forget to backup and get the files on fixed dates. My backup plugin, for example is set to back up every week and sends these backups to me via email. You can of course choose whatever works for you best.

1.2 Use Strong Passwords

Strong passwords are essential for user with lots of privileges such as the administrator. Without them your blog will be vulnerable to so called brute force attacks. Essentially these are attacks in which the attacker tries to guess the password by going through a password list. If you use secure passwords then the chances of breaking that password are low.

Here are some tips as to what secure passwords should include:

  • use at least 1-2 numbers
  • use upper and lower case characters
  • use special characters such as [email protected]#…

You should also not use passwords such as your birth date or hobbies of yours. These kind of passwords are very insecure since hackers can find out personal information easily.

Another important step you have to take is to have lots of different passwords. It is nice to have just one single password and access everything through it, but imagine what happens if someone knows this password. He can basically access all your accounts.

For that reason use lots of different passwords.

1.3 Keep Up with Patches and Updates

This is another vital step in securing your blog. Patches and updates are created in order to fix security holes and to add to the product’s functionality. There is no reason not to install them.

Essentially you should also keep yourself informed about changes in WordPress and vulnerabilities in general. I therefore advise you to follow these two feeds:

  1. WordPress Development
  2. BlogSecurity.net

The first one is the WordPress development feed where new releases and latest updates for WordPress are posted. The other is the feed from BlogSecurity.net. These guys often post vulnerabilities existing in plugins or in WordPress.

1.4 Use SSH instead of FTP

FTP in general is not as secure as people think it is. Your FTP credentials are usually not encrypted and easy to capture.

A very secure alternative to FTP is SSH. SSH uses a straight forward algorithm to encrypt all the data sent through it, including files. Read this story and you might change your mind about using FTP to upload!

1.5 Use Supported WordPress Themes

The WordPress core usually contains most vulnerabilities, but WordPress themes also do. Themes can pose a security risk because not every web developer knows how to code securely.

For this reason it is good to stick with a theme that is supported and updated from time to time. Supported WordPress themes are generally available for some money, but it’s better to be safe than sorry. These paid themes are called premium themes. Such themes are offered by web sites such as Woo Themes, which I personally use.

Another important aspect about professional templates is that when you run into trouble, you have a place that can help you fix it.

1.6 Scan Plugins for Viruses After Download

Today you can so easily download plugins and install them within seconds on your blog. But you have to be careful with what kind of extensions you download. Plugins can contain malicious code. Because of this it makes sense to scan for malware right after downloading them.

For this task it’s best to use Anti-Spyware and Anti-Virus software. Newer operating systems such as Windows Vista automatically check for viruses after downloading files. If you use an old operating system I would recommend scanning your download directory maybe once a week or right after downloading new files.

1.7 Change the Database Table Prefix

In order to make your database more secure you should change your database table prefix. The default prefix is wp_
and it should be changed to something different, something more complicated and harder to guess.
The prefix can be changed in the wp-config.php file.

You try to change the table prefix wp_ to something different like 5rt30k_.

$table_prefix = 'wp_'; // Only use numbers and letters and underscore

After changing the line in the wp-config.php file, you need to save these changes. If you already have installed WordPress then you need to take additional steps, as outlined below. Otherwise you are done.

Changing the Table’s Names
As already mentioned, only follow this step if you have already installed WordPress and you have followed the previous step.

The next thing to do is to change the name of the database tables to fit to the chosen prefix. You need to issue these SQL commands (probably through your phpMyAdmin account).
RENAME TABLE wp_comments to 5rt30k_comments;
RENAME TABLE wp_links to 5rt30k_links;
RENAME TABLE wp_options to 5rt30k_options;
RENAME TABLE wp_postmeta to 5rt30k_postmeta;
RENAME TABLE wp_posts to 5rt30k_posts;
RENAME TABLE wp_terms to 5rt30k_terms;
RENAME TABLE wp_term_relationships to 5rt30k_term_relationships;
RENAME TABLE wp_term_taxonomy to 5rt30k_term_taxonomy;
RENAME TABLE wp_usermeta to 5rt30k_usermeta;
RENAME TABLE wp_users to 5rt30k_users;

But you are still not done. You need to change some fields in the options and usermeta tables to make WordPress work correctly.
UPDATE 5rt30k_options SET option_name = REPLACE(option_name, 'wp_', '5rt30k_');
UPDATE 5rt30k_usermeta SET meta_key = REPLACE(meta_key, 'wp_', '5rt30k_');

If some plugins don’t perform right then try the following queries to find out which table needs to be changed.SELECT * FROM 08xyz15_options WHERE option_name LIKE 'wp_%';
SELECT * FROM 08xyz15_usermeta WHERE meta_key LIKE 'wp_%';

Most of this code is taken from another post on how to make WordPress more secure, but it is written in German.

There is also a plugin available which does all of the above, it is called WordPress Prefix Table Changer.

2. File Protection

Files are what makes up a web page. By protecting your files you are going to harden your WordPress blog.

2.1 Limit Access to wp-includes and wp-content

Wp-includes and wp-content are important WordPress directories. Users should only be able to access certain file types within these directories. These file types include pictures (.jpeg, .gif, .png), Javascript (.js), CSS (.css) and XML (.xml).

It makes sense to prohibit access to all other types of data. The code below will allow pictures, Javascript, CSS and XML files but will not allow any other data. This should be placed in the .htaccess file within wp-includes and wp-content.

Order deny,allow
Deny from all
<Files ~ ".(xml|css|jpe?g|png|gif|js)$">
Allow from all
</Files>

If you are using a cache with WordPress such as the WP Super Cache plugin then you also need to allow the object lock.
In some cases plugins also need direct access to php files. In this case you need to also allow these special file types:

Order deny,allow
Deny from all
<Files ~ ".(php|lock|xml|css|jpe?g|png|gif|js)$">
Allow from all
</Files>

As mentioned above, place this code in an .htaccess file within wp-includes and wp-content.

2.2 Secure wp-config.php

Wp-config.php is a very important file since it contains all the access information and keys that are vital to securing your blog. Again we can secure the file by adding these lines to the .htaccess file in the WordPress root directory (where the wp-config file is):

# protect wp-config.php
<files wp-config.php>
Order deny,allow
Deny from all
</files>

This code denies everyone access to the wp-config.php file.

2.3 No Directories Should Be Available for Browsing

Another vital change concerning WordPress security is to prohibit people from browsing your web site directory structure. If you want to see what this looks like just enter “index of” something into Google and Google will list all the web sites that allow the browsing of directories.

In order to stop this behavior all you have to do is add the line of code from below to your .htaccess file in the root directory of WordPress.

Options All -Indexes

This will stop the behaviour once and for all.

2.4 Keep Search Engine Crawlers from Indexing the Admin Section

Search engine crawlers index almost every content as long as they are told not to do so. Your admin section being indexed in search engines can be a major security threat. People searching for vulnerable blogs could find your blog more easily.

Therefore it is good to just keep crawlers away from all WordPress directories. The easiest way to do it, is to create a robots.txt file in your root directory. Then place the following code in the file:

Disallow: /wp-*

2.5 Secure Your Plugin Directory

The plugins you use can tell a malicious user a lot about your web site therefore it is wise to hide them.

You can easily hide the plugins. First of all open up a text editor and just create an empty file named index.html . The next step is to upload this file to your wp-content/plugins/ directory.

3. User Security

Users are the very essential of every WordPress blog. In order to protect your users and your blog you need change a few things.

3.1 Delete the Default Admin Account

By the deleting the admin account malicious users do not get to know your user name so easily. As every WordPress installation comes with a admin account, hackers will have an easier time breaking into your account since the already know your username.

You cannot delete your administrator account right away if you do not have a new admin account, so follow these steps:

  1. create a new administrator account
  2. log out of WordPress
  3. log back in with the new admin account and password
  4. delete the old account

3.2 Change Default Access Rights for Users

The default access rights are pretty secure but if you want to be on the safe side and have more control over the rights every user has, then this is essential.

It is pretty simple to set it up. All you have to do is:

  1. Download the Role Manager plug-in
  2. Upload it to your WordPress blog
  3. Activate it

Then go to the Users section of your blog. There you can set up the Role Manager plugin to suit your needs.

3.3 Delete Inactive User Accounts

Inactive user accounts are annoying, they can also become a security risk. Sometimes, for example, people choose weak passwords and there are only few ways to protect against it. If the account is inactive but still on your blog, malicious users could use this account to get access to your blog.

Therefore the best thing to do is to just delete inactive user accounts in WordPress. In order to do that go to your WordPress dashboard and click on Users. This takes you to the page where every user will be listed.

Then go ahead and delete the ones you know are inactive.

3.4 Add WordPress Authentication Keys to wp-config.php

Adding WordPress keys is another important security measure. These keys should be random and work as salts for WordPress cookies thereby insuring better encryption of user data.

Use the WordPress Key Generator to generate these keys and just replace, in the wp-config.php file, the lines below with the generated ones:

define('AUTH_KEY', 'put your unique phrase here');
define('SECURE_AUTH_KEY', 'put your unique phrase here');
define('LOGGED_IN_KEY', 'put your unique phrase here');
define('NONCE_KEY', 'put your unique phrase here');

That’s actually all you have to do.

4. Template Security

WordPress templates, or themes, are also important in ensuring a safe blog. These little tweaks are important and also easy to follow.

4.1 Drop the WordPress Version String

<meta name="generator" content="Wordpress 2.5" />

The version string that WordPress automatically adds to your theme is important because it gives a malicious user the information about whether a blog is patched or not. If it is an outdated version the attacker will immediately start to look for security holes that were made public about that specific WordPress version.

WordPress usually automatically adds this version string to your theme. The line of code below will tell WordPress to not to add the version string to your header. All you have to do is add the code to your functions.php file.

<?php remove_action('wp_head', 'wp_generator'); ?>

Now take a look at the source code of your web site. If the generator meta tag is still in there then you should check whether your header.php contains such a line:

<meta name=”generator” content=”WordPress <?php bloginfo(’version’); ?>” />

If that’s the case then go ahead and delete it.

4.2 Correct Bad Coding Habits

Bad coding habits are rather hard to figure out. But once you know them there are easy to spot and they also make you more aware of how not to code.

If you find code like the one below in your search.php file then you should immediately change it. This poses a security threat as people are able to search your whole web server:
<?php echo $_SERVER [’PHP_SELF’]; ?>
A good alternative is to use this:
<?php bloginfo ('home'); ?>
This is a good coding practice (a German article) and doesn’t allow people to search for data they shouldn’t have access to.

Another bad piece of code is the one below. It allows people to add malicious code to your web site. This kind of code can be found in search and title tag templates.
<?php echo $s; ?>
Instead of echoing the variable directly, it’s safer to add some filtering to it:
<?php echo wp_specialchars($s, 1); ?>
So much for template security. I hope this has given you an idea of what to search for in WordPress themes.

5. Administration Login Protection

The administration section is very important to every web site owner. Protecting this part of your blog will be worth the effort in the end.

5.1 Use HTTPS When Logging in to Your Dashboard

HTTPS is the secure version of HTTP. When using HTTPS your data, i.e. passwords and user names, are not send in clear text, instead they are encrypted. This makes it harder for people to intercept and rightly decode your password and user name.

If you want to use HTTPS when logging into your WordPress dashboard, then you can use one of the codes below and add them to wp-config.php.

define('FORCE_SSL_LOGIN', true);

The code above forces WordPress to use SSL when logging into your administration panel but only when logging in. It does not enforce the use of SSL while using your dashboard.

define('FORCE_SSL_ADMIN', true);

This code snippet makes WordPress use SSL not only when logging in but also when using your WordPress dashboard. Because all the data is never sent in clear text, it has the negative effect of slowing down the administration area.

Instead of doing all these things manually you can also just add a plugin like Admin SSL.

5.2 Block Access Attempts to wp-admin Directory

The wp-admin folder is one of the most important directories on your blog. You can access your dashboard through it. Blocking other people from accessing this directory is an essential step in securing your blog.

You can do this by creating an .htaccess file in the wp-admin directory. Add the code below to it but change the IP-addresses to your own ones. If you don’t know what your IP-address is then just visit WhatIsMyIP.

AuthUserFile /dev/null
AuthGroupFile /dev/null
AuthName “Access Control”
AuthType Basic
order deny,allow
deny from all
# whitelist home IP address
allow from 64.233.169.99
# whitelist work IP address
allow from 69.147.114.210
allow from 199.239.136.200

It does not make sense to use this code if you have lots of people writing on your blog, especially if they constantly change. The problem is that you always need to add/delete ip-addresses, based on who needs access to your blog at the moment.

Another drawback is when your Internet provider assigns you a dynamic IP-address, meaning that your IP-address is changing constantly. If that’s the case then don’t add the code to the .htaccess file.

5.3 Restrict the Number of Failed WordPress Login Attempts

Restricting the number of failed attempts prevents users from using brute force techniques on your WordPress account. A brute force attack is an attempt to find out the user password through trying out every single possible password.

As a counter measure there are plugins that automatically ban a user for an hour if he got the password wrong three times in a row. Login Lockdown is one of these WordPress plugins.

5.4 Hide WordPress Dashboard Log-In Errors

Have you ever noticed that when you try to login with an exisiting username and a wrong password you get a message saying Error: Incorrect Password. If you login with a non-existant username and some password a different message shows up reporting Error: Invalid Username.

These different functions help malicious users to figure out what kind of usernames exist. They can just try out different usernames using always the same wrong password and they will know which usernames exist.

Therefore I advise you to add the following line to your functions.php file, it’s definitely going to help you protect the admin section:

add_filter('login_errors',create_function('$a', "return null;"));

Every time an error now occurs a blank line will appear. Try it out.

6. Conclusion

As you have seen, there are many steps you can take in protecting your WordPress blog, some of them being more important then others. I hope that this guide was helpful to you. Over the time I will update this guide as new information comes available.

If you have any questions, concerns or just want to talk, then go ahead and contact me.