The standard WordPress install done by automated services such as Fantastico is something that should be avoided. The default settings in a default install leave a WordPress site more susceptible to security breaches which is why you should spend a little extra time when installing your WordPress sites in order to “harden” them from hackers as much as possible.
The following 12 options deal with the wp-config.php and .htaccess file, and with just a few modifications and additions to just these files, you will have increased the security of your WordPress site to a much higher degree. The first hack is user generated, the next three deal with the wp-config.php file, and all the rest are .htaccess additions.
1. Change the admin username from “admin”
Up until WordPress 3.0 was released, the initial administrator was created at the time of install with the username of “admin”. Most people continue to use this administrator name long after their blog is installed. This is a poor practice from a security standpoint, as anyone who tries to hack into your site more information than they should have.
If you are installing WordPress for the first time with version 3.0 or newer, choose a name other than “admin” when installing the software. Or if you have a pre-existing site with the administrative name of “admin”, create a new administrator account with a different name and delete your old one.
2. Change the WordPress database prefix
The default installation method in WordPress creates a database consisting of tables that all have the prefix of “wp_”. By leaving the default table prefix setup in the wp-config.php file you would be giving too much information to any malicious person wishing to infiltrate your database.
In the default wp-config.php file (or wp-config-sample.php file if you haven’t changed the name yet), the database table prefix setting is located in the following section:
/** * WordPress Database Table prefix. * * You can have multiple installations in one database if you give each a unique * prefix. Only numbers, letters, and underscores please! */ $table_prefix = 'wp_';
Change the default table prefix to anything other than “wp_”, just be sure to follow the accepted inputs stated by WordPress (only numbers, letters and underscores allowed). The following example is more than adequate for a WordPress site:
/** * WordPress Database Table prefix. * * You can have multiple installations in one database if you give each a unique * prefix. Only numbers, letters, and underscores please! */ $table_prefix = 'H8xl9r_';
It is possible to change the table database prefix long after you have installed WordPress, but it takes a little more effort. Info on doing this can be found at the Tdot Blog
3. Change the default Keys and Salts
Another part of the default wp-config.php file that is largely ignored is the Keys and Salts section. According to the WordPress Codex, A secret key is a hashing salt which makes your site harder to hack and access harder to crack by adding random elements to the password. The Keys and Salts section of the wp-config.php file looks like this:
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');
define('AUTH_SALT', 'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT', 'put your unique phrase here');
define('NONCE_SALT', 'put your unique phrase here');
Be sure to enter any kind of lengthy string of random letters, numbers and symbols to replace the originally provided phrase.
4. Remove post revisions
Have you ever seen the bottom of your post edit screen and seen a seemingly endlist list of post revisions? These revisions take up space in your database and if they get large enough, they will slow down the overall performance of your site. You can remove this post revision feature by adding this to your wp-config.php file:
define('WP_POST_REVISIONS', false);
You can add this almost anywhere in the wp-config.php file, but my personal preference has always been to add it at the end of the Keys and Salts section like so:
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');
define('AUTH_SALT', 'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT', 'put your unique phrase here');
define('NONCE_SALT', 'put your unique phrase here');
define('WP_POST_REVISIONS', false);
Now let’s move on to .htaccess hacks
5. Prevent directory browsing
You shouldn’t leave your site totally open to curious visitors, letting them poke around areas of your site which really shouldn’t be open for viewing. To prevent people from accessing folders they shouldn’t be poking around in, add this to your .htaccess file:
Options All -Indexes
6. Prevent others from hotlinking your images
I’m not a fan of other people hotlinking images from my sites. It really is nothing more than bandwidth theft, and thankfully it is very easy to prevent this type of behavior with a small insertion in the .htaccess file as well. Here are two examples of what you can enter into your .htaccess file to stop this from happening; the first example just won’t allow it to happen, and the second example provides an alternative image to anyone trying to hotlink your images (be sure to enter your domain name in place of the “yourdomain” in the examples).
Example 1
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+.)?yourdomain.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule .*.(jpe?g|gif|bmp|png)$ - [F]
Example 2 (provides alternate image)
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www.)?yourdomain.com/.*$ [NC]
#RewriteRule .(gif|jpg)$ - [F]
RewriteRule .(gif|jpg)$ http://www.yourdomain.com/stealingisbad.gif [R,L]
7. Protect your wp-config.php file
If you are going to lock down your important files, don’t forget about your wp-config.php file. This file contains some very sensitive information, such as your database login credentials, and a little extra security with this file is never a bad idea. Add this snippet to your .htaccess file to protect it:
<files wp-config.php> order allow,deny deny from all </files>
8. Block No Referrer requests
Many of the spammers use bots to try and get their links injected onto WordPress sites through the commenting section. One thing that often identifies these bots is that their arrival to your site is recorded as coming from nowhere. Stop these spammers in their tracks with this addition to your .htaccess file (and be sure to enter your domain name instead of “yourblog.com”):
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .wp-comments-post.php*
RewriteCond %{HTTP_REFERER} !.*yourblog.com.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) ^http://%{REMOTE_ADDR}/$ [R=301,L]
9. Protect your .htaccess file
After spending some time using .htaccess to protect your site it only makes sense to add some security to the .htaccess file itself! This little bit of code supplies the extra protection:
<files .htaccess> order allow,deny deny from all </files>
10. Protect the wp-content and wp-includes folders
More security for your site can be gained by inserting a .htaccess file inside your wp-content and wp-includes folders to limit what files can be accessed from there. I like to only allow image files, css files and javascript files and leave all the php files left alone. This is done by creating a new .htaccess file in each of the above mentioned folders and inserting the following into them:
Order Allow,Deny Deny from all <Files ~ ".(css|jpe?g|png|gif|js)$"> Allow from all </Files>
A lot can go wrong with the above .htaccess entry, such as certain functions being blocked, so if you find yourself needing to allow a plugin through (such as the universal video plugin), then add this right after the above snippet:
<Files "universal-video.php"> Allow from all </Files>
11. Protect the wp-login.php file
This modification to the .htaccess file works best if you have a static IP address from your Internet provider. If your IP address never changes, then you can block everyone else but you from accessing the login page with this addition to your .htaccess file:
<Files wp-login.php> Order deny,allow Deny from All Allow from 123.456.789.0 </Files>
The above mod is great for blocking out everyone but yourself, but keep in mind that if you travel anywhere and then try to login to your site, you will be blocked as well (unless you have set up a SSH tunnel to your home network).
12. Protect the wp-admin folder
Just like the wp-content and wp-includes folders, the wp-admin folder can also be locked out to anyone except the site’s administrator. Simply create a new .htaccess file in the wp-admin folder and fill it with this:
AuthUserFile /dev/null AuthGroupFile /dev/null AuthName "Example Access Control" AuthType Basic <LIMIT GET> order deny,allow deny from all allow from xx.xx.xx.xx allow from xx.xx.xxx.xx </LIMIT>
This little bit of extra security will help with your overall site security. Any visitors attempting to access your wp-admin folder will be greeted with a forbidden message.
13. Disable the server signature
By default, certain errors committed on a website will end up with server generated error messages which often include information about the server itself. This kind of information is not something you should be broadcasting to others, so let’s disable this output through the .htaccess file with this little snippet:
ServerSignature Off
Final Thoughts
By implementing all or some of these mods to your WordPress site, your overall site security will stand head and shoulders above most other WordPress sites. However, not all of these examples may be ideal for your needs or situation. Play around with these examples, and always be sure to make backups before you get too crazy!
References and sources not previously cited:
Reuben Yau
Josiah Cole
WP Shout
Edit: As pointed out by Ron from Itty Bitty Talks in the comments, I totally neglected to include the option of removing the WordPress version in the head of the site. This is something I do every time when I build WordPress sites, so my oversight is inexcusable.
Now there are several wrong ways to remove the WordPress version from your site, and this is the way I recommend to get this information removed from your site.
Open the header.php file in your theme folder and look to see if you see this line before the closing tag:
<meta name="generator" content="WordPress <?php bloginfo('version'); ?>" /> <!-- leave this for stats -->
You might think that this would be enough to remove the WordPress version from showing up in the meta information, but you would be wrong. The newest versions of WordPress include a built-in function that also generates this info.
To completely remove the WordPress version from showing, you have to also open up your theme’s functions.php file and add this line to it:
remove_action('wp_head', 'wp_generator');
By doing the latter step and possibly the first one as well (if your theme had the first line in there) you will have completely removed your blog’s version of WordPress from being shown. And that’s a good thing, because quite frankly, no one besides yourself and possibly your priest or spouse needs to know which version of WordPress you are running.
