Web 101: Fixed a hacked site and prevent it from happening again – Part 2
Warning: mysql_query() [function.mysql-query]: Unable to save result set in /home/swank/public_html/wp-includes/wp-db.php on line 1879
In my previous post I talked about what to do to fix a hacked site. This post is about things you can do to make WordPress more secure so that something like that doesn’t happen again (or ever). The basic things were mentioned in the last post: change your passwords regularly, use strong passwords and always have the most current version of WP. But here are some other things you can do:
DON’T FORGET ABOUT YOUR PLUGINS! Security vulnerabilities can be just as much of an issue with plugins so they need to be updated, too. The newest version of WP makes this easier than ever. It tells you when you have a plugin that needs updating (a bubble pops up on the plugins link like it does for new comments) and all you have to do is press on “upgrade automatically”. On many servers, you don’t need to do anything it will upload and install the plugin in seconds. If your server isn’t set up that way, then you just need to put in your ftp host (in most cases, ftp.yourdomain.com), username and password. Your host would have sent all this info to you, so you should have it. If you don’t then get it, this is really important information to have.
ADD SECRET KEYS TO YOUR WP-CONFIG.PHP. As of WP 2.5 and then later in 2.6, they introduced the addition of several keys that can be added to increase security for your blog. Open up wp-config.php and find this line:
define(‘DB_HOST’, ‘localhost’); // 99% chance you won’t need to change this value
Under it add these:
You need to put a different random string of characters in each line. You will never have to remember these, so make them as long and as random as possible. This handy site will generate a random string for your every time you refresh the page.
EDIT UNSECURE TEMPLATE TAGS.
In search.php or searchform.php find this:
<?php echo $_SERVER ['PHP_SELF']; ?>
And replace it with this:
<?php bloginfo ('home'); ?>
That makes it so it can only search your blog and not your entire server.
Also check search.php, searchform.php or header.php for this:
<?php echo $s; ?>
This allows malicious code injection so replace it with this:
<?php echo wp_specialchars($s, 1); ?>
MAKE IT IMPOSSIBLE FOR SEARCH ENGINES TO INDEX WORDPRESS FILES. It’s not a good idea to let search engines like google index every single part of your site, specifically your WordPress files. Say that a vulnerability is discovered in one of the files in the wp-admin folder. A hacker could just google that file name and the first site at the top of the list is the one he’s going to hack today. To prevent this simply open up notepad or an HTML/text editor and add this:
Name it robots.txt and upload the file to your WordPress directory (same place where you should find wp-config.php and .htaccess). This not only disallows search engines from indexing private WP files, but also prevents them from indexing redundant files (which search engines can read as trying to spam them).
DON’T ADVERTISE WHAT VERSION YOU ARE RUNNING. If all your blog pages say “Powered by WordPress 2.5” (when the current version is 2.6.2), then you are just asking to be hacked. Take that version out of your template. In most cases this is going to either be in the sidebar.php or footer.php files. Look for either of these template tags and delete them:
<?php get_bloginfo('version'); ?>
<?php bloginfo('version'); ?>
Also, check header.php, look for this line and delete it:
<meta name="generator" content="WordPress 2.5" />
Unfortunately, in 2.5+ WordPress has started inserting this automatically. This is bad because hackers only need to put that line into a search engine to find people using old versions of WP. If you have your robots.txt in place then this is not a major issue, because your template won’t be showing up. But if you are still uncomfortable with having your version so public (they only need to view the page source to see it), then open up notepad or an HTML/text editor and paste this in:
<?php remove_action( 'wp_head', 'wp_generator' ); ?>
Save as functions.php and upload it to your theme folder. If you have widgetized sidebars, then you probably already have a functions.php, so just edit the file and insert that code in there.
*Hat tip to Binary Moon for this.
MAKE SURE YOUR DATABASE PASSWORD IS NOT THE SAME AS ANY OTHERS. Your wp-config.php is a very easy file to find. It has your database password sitting right inside it. You absolutely must make sure that your database password is completely different from your WordPress password and your FTP/cpanel password. If you are using the same password for all, a hacker can easily find this file and get in everywhere. If it is the same, then it will probably be simpler for you to change your WP and FTP passwords. But changing your database password isn’t too hard through cpanel (click on MySQL and add a new user and password, then assign that user to your WP database, then go and update your wp-config.php file with the new user info).
DON’T USE THE DEFAULT SETTINGS. Most of the time, when you install WordPress it automatically gives you the username ‘admin’. Hackers know this, so it can be unsafe because then all they have to do to get in is guess the password. Go to Users and add a new username for yourself. For the role, choose Administrator. Once you’ve added your new username, log out and log in as the new user. It’s better to have your nickname (what is displayed publicly on your blog) be different from your username, so you might want to edit your new user profile to change that. Then check the box next to the admin username and delete it. It will ask if you want to attribute all of admin’s posts to someone else, choose your new username. This will transfer all your posts over to the new username.
CHANGE THE DATABASE PREFIX. This is really a recommendation for when you are setting up a new installation of WordPress. It’s not recommended for already installed blogs, especially for beginners as you can severely mess up your blog. But if you are setting up a new WP blog, it’s a simple thing you can do to help increase security. In the wp-config file, just look for the line that says:
// You can have multiple installations in one database if you give each a unique prefix
$table_prefix = ‘wp_’; // Only numbers, letters, and underscores please!
wp_ is the default prefix and hackers know this, so this is just another case of changing the default WP options. Change it to anything you want, though you’ll probably want to keep it short and random like kb_, cc_, ibc_, aba_, etc.
The plugin I mentioned in my previous post, WP Security Scan, will actually change the prefix for an already installed blog, but proceed with caution and make sure to backup your database before you try it.
Here are some other plugins I know of that can help make your blog more secure:
AskApache Password Protect – The author describes this plugins as creating a virtual wall around your blog to stop attackers from exploiting any kind of vulnerabilities. Has some server requirements, though, so make sure you have those before installing.
Login Lockdown – Records the IP of every failed login attempt of your blog, the IP gets locked out after a certain number of failed attempts. You can set this number and how long they get locked out, but the default is 3 failed attempts locks them out for an hour.
Stealth Login – You can customize the login and registration URLs of your blog. Just another example of changing the default options, making it harder for hackers to get in.
Secure WordPress – This plugin removes the error info on the login page (so it doesn’t say “Wrong Password” anymore when you try to log in), removes the WP version from your theme and adds an index file to your plugin directory, so it can’t be accessed directly.