How to Stop Your WordPress Blog Getting Hacked
Unbeknownst to most people who set up a WordPress powered website, they are also putting up a big banner saying, "I am ripe for hacking." While the situation is better than it was two years ago, WordPress is still a major target for hackers and some of the problems like lack of proper escaping (relatively simple to fix) seem to have been forgotten about.
An example of a hacked WordPress blog.
The WordPress hackers are more or less comprised of two groups: people who want to use hacked WordPress sites as cloaked link farms and hobbyist hackers – often from Turkey. If you have a relatively good knowledge of HTTP and PHP, you can probably hack a WordPress site within 30 minutes by using software vulnerability lounges like Milworm to find out about vulnerabilities.
Removing Footprints – Stop Hackers Finding You
1 – Remove the Footer Credit – Most WordPress templates will come with a link back to WordPress in the footer saying, "Powered by WordPress". If you don't want to get hacked, this absolutely has to go. It is used as a marker by hackers who query search engines to compile lists of WordPress sites. This is known as dorking; implying that people who leave such footprints on their sites are dorks. Removing this will probably stop you from getting hacked as your site will probably not be found once it is removed. If you would like to give credit to WordPress for making a free publishing platform in some other way, you could link to them on your about page.
To remove the footer credit, open up wp-content/{name of the theme you are using}/footer.php and delete the link to WordPress.
2 – Remove the Meta Generator Tag – Most WordPress templates will also come with a HTML tag in the head like this:
<meta name="generator" content="WordPress 2.7" />
This has to go too as it gives away what version of WordPress you are using. All a hacker would have to do is look up a hack for your version of WordPress and if you are vulnerable (some vulnerabilities require certain server settings or environments) they will take you down.
To remove the meta generator, open up wp-content/{name of the theme you are using}/header.php and delete the meta generator tag.
3 – Remove the Generator Tag in the RSS Feed – WordPress also gives away which version you are using in the RSS feed with a generator tag like this:
<generator>http://wordpress.org/?v=2.7</generator>
Again, this gives away the version you are using so is particularly dangerous. RSS feeds are another way in which hackers compile lists of sites which they might be able to attack.
To remove the RSS generator, open up wp-includes/general-template.php and search for the function called the_generator (around line 1858). It will look like this:
and place a hash (#) in front of the word echo, so it looks like this:
4 – Remove Other Footprints – There are a number of other ways that someone might be able to tell that your site runs on WordPress, such as installing it at, http://domain.tld/wordpress/ and if you have links to specific WordPress files names, such as wp-login.php. The later can easily be found using a search engine, e.g. WordPress Logins
Two file names that are visible on all WordPress installs will be the the wp-content/ directory (where WordPress stores media) and the wp-comments-post.php. You can change the name of the wp-content directory in the WordPress admin under settings > miscellaneous. To change the wp-comments-post.php, you will need to edit your template to use a different URL and forward the new URL to wp-comments-post.php. It is unlikely anyone uses these methods to find WordPress blogs to hack, but they are considerations you can take if you want to be extra careful.
Also make sure you have deleted the licence.txt and readme.html in the root directory.
Locking Your Install Down
5 – Disabling Indexes – Disabling indexes means that when someone navigates to a directory on your server, it will not give them an output of the folders and files in that directory. This is particularly important as a number of WordPress hacks target vulnerabilities in plugins. So if your wp-content/plugins/ directory is browsable, you are going to be giving away what plugins you are using. This may be used to target sites that use a particular plugin or if you have enemies someone might use it to find a vulnerability specific to one of your plugins. Due to lack of security, many sites have their plugins directory indexed: Plugin directories
If you are using Apache as a web server (the most popular choice) you can disable indexes by adding one line to .htaccess in the root of your WordPress install – that is the main directory with index.php in it. Simply add Options -Indexes anywhere in the .htaccess file. If you ever need to enable indexes in a directory, all you need to do is add Options Indexes to a .htaccess file in that directory. For those who are not using Apache, other options will be available for your sever. Alternatively, if you are partial to botches, you can put an index.html file in all directories you don't want people to be able to browse. So, when someone loads a directory, they will just be shown the index.html.
6 – Blocking Server-side Directories – Blocking directories that contain files that are only needed by your server is an essential aspect of any site's security. There are a few reasons for this, including:
- If your server has a problem with PHP (like if someone removes the Apache PHP module), your server may start outputting PHP files literally
- Some text editors will create backup files like, index.phps or index.php~. These can be uploaded to the server, accessed by undesirables; giving away your database credentials. These files can get indexed by search engines for easy targeting.
- There are also ways in which someone can detect what platform you are using if the platform uses unique directory names, as WordPress does.
Due to WordPress' architecture, it is not possible to block all directories that should to be blocked. The main directory to block is wp-includes/. You can do this by adding the following line to .htaccess:
RewriteRule ^(wp-includes)\/.*$ ./ [NC,R=301,L]
To block further directories, separate each directory with a pipe like so:
RewriteRule ^(wp-includes|another-dir)\/.*$ ./ [NC,R=301,L]
7 – Hiding the Admin – Securing the administration is important as it is an easy place where your username and password can be yoinked. First of all, you will want to put the admin on an encrypted connection (SSL). If you have cPanel, I believe this can be setup from there. If you do not know how to do this you will need to get someone to do it for you or ask your hosting company. Using a secure connection for your admin is important because without it your login credentials will be banded around the internet as plain text. They will also be stored in your server's log files as plain text – not good if a malicious individual or a disgruntled server admin gets access to your server.
Renaming the admin directory is also a good idea. By default it is wp-admin/. However, this isn't an easy job for those who do not have a decent understanding of PHP. Alternatively, you can password protect the directory. This can be done from cPanel.
8 – Move the Config Data – As mentioned above, some text editors will make backups of your PHP files which can be opened by anyone, or if you have server problems your PHP files could be output as text. This opens up the problem of someone opening up your wp-config.php file and snafing your database credentials. The best thing to do is:
- Copy the contents of wp-config.php
- Create a new file in a directory (e.g. wp-includes/conf.php) and paste the contents into it
- Require the location of the new config location. This will look something like:
- Save the new wp-config.php
It is essential that your new config file is in a directory that you have blocked from outside access using the method in point 6. Otherwise, you will just be telling people where you have moved your config.
A search on Google shows a number of sites with their database credentials ripe for the picking: sitting ducks
9 – Database Encoding – In wp-config.php, you are able to select your database encoding. It is advisable to use UTF-8 as other character sets are vulnerable to SQL injection since WordPress doesn't use multi-byte character escaping.
10 – File Permissions – Use the below file permission for optimal file system security:
| Directory | Permission |
|---|---|
| ./ | 755 |
| wp-admin/ | 755 |
| wp-content/ | 755 |
| wp-includes/ | 555 |
WordPress Trojan Horses
11- Themes and Plugins - Last but not least, you can run into serious trouble by installing plugins and using themes without checking them for malicious code. If you don't know PHP, I'd recommend only installing plugins and themes which are listed in the official WordPress directories as I'd image those are veted for nasties. Although with plugins like pennispress getting into the official directories, it is difficult to know who to trust these days :|
Comments
Thanx for the advices!
Thanks, I didn't even realize that this sort of thing was a problem. I'll work on fixing my site ASAP.
David nice article ... really impressed I will link to this from our own site. Nice to see your written skills are still strong.
David, this is brilliant. The first thing I am going to do is remove that imprint and then I am going to analyze the rest of this post.
I meant to leave a comment on http://semlabs.co.uk/seo-help but there was no comment form so I just Tweeted about it instead. Have done the same for this, and will stumble it as well. Once again, this is an absolutely awesome post.
Glad to help :) Thanks, I already noticed your tweet as I am constantly using SEO for Firefox. The most important things are to get rid of the footprints and disable indexes as most if not all WP hacks will be carried out automatically by scripts on a load of blogs harvested using the "powered by WordPress" dork. There are even out-of-the box WordPress hacks provided by good folks such as RGod
When I edited my pages they went to the top of the RSS feed, which is why that didn't have any comments; fixed the issue, but that help one got stuck in CommentLuv for a few weeks.
No worries David. I noticed my Theme didn't have a link to WP, so it is possible the developer knew about this in advance.
This post is excellent! I came here on the recommendation of Sire, and I'm glad I did.
I'm not sure if I want to go with the steps 5-10 as I'm worried that they may affect the installation of plugins or upgrades in the future.
Any idea about that?
Hi,
I'd say points 1 - 6 are pretty essential things you need to do with WordPress and point 7 is highly recommended. Point 8, 9 and 10 are really more extreme measures. You're right though, points 5 and 6 could cause issues with WordPress plugins. I'm not sure - don't really know much about WordPress plugins. If you don't use .htaccess to restrict access to your plugins folder, I would put an index.html file in it so no one can see the directory listings.
Wow, this was fantastic stuff! I'll have to admit that some of it was over my head, but for the stuff that wasn't, I've already made the changes. Thanks!
Glad to be of help. Steps 1 - 4 should be enough to stop you ever getting hacked, since it's really unlikely a hacker will find your site once you have removed the footprints.
Great tips... I'll have to implement some of these since my site was recently messed with. Thanks for sharing!
~ Kristi
You can find some alternative views here
Although, from the content of your last post it seems you know your way around PHP.
Great post.
I have some points already done.But, some points are not yet protected.
will do it.
We also have an online tool to check the security of your wordpress blog:
http://sucuri.net/?page=scan
With a document showing different strategies to secure it:
http://sucuri.net/?page=docs
thanks,
--dd
Wow, you have a huge list of tips and tricks. I knew some of them, but others I had no clue about them.
Thanks for sharing this, this is very important to newbies as well as pros.
Great post. I never knew about some of these. Thanks for the share.
Some good tips David, users should also ensure that they have a strong password to thwart brute force dictionary attacks.
Great advice for many there :)
Good point. There are numerous other things that have sprung to mind due to the recent spate of hacks such as using mod_security and the file monitor you have listed on your site.
Thanks for this I be implementing in my blog
My site got hacked last week and i've spent up until then getting back to normal. You've just set out my tasks for the weekend, thanks for the great advice.
Excellent post and this has just set it out how to easily try and block a site from hackers, a must on my to do list.
I'm about to install wordpress on the back and of my site, am I actually allowed to remove the Wordpress links from the template without conflicting with any licence agreement terms for open source software? or do I first need to get permission then remove.
I remember reading somewhere that WordPress appreciate people not removing the link from the bottom. Open source often requires "attributation", which means they just want credit in some form. In the case of WordPress, you could just mention on your about page that your site is built on WordPress.
great tips, now im using plugin auto update wordpress i hope not get hacked like others
Good tips but one way you could improve is to start off with a content section.
Excellent article. What about setting your /wp-admin and /wp-content folders to a 705 permission? Wouldn't that be just a little bit more secure but not really interfere with anything?
For step 8, I'm a little confused on where to put code. I understand copying the current content of the wp-config.php and putting that into a new file/directory and saving.
But what do I do with the original wp-config.php file and in what file do I put the require code you showed us?
Thanks
Yeh those permissions may be better. I was taking a bit of a gung ho approach.
Again, point 8 was an extreme measure, but worth taking IMO. Basically what I was saying you can do is move the contents of your wp-config.php to a file which cannot be accessed by HTTP (something that is blocked by .htaccess) and then requiring that new file in the actual wp-config.php. The main reason for this is if there is a problem with the server and files are not being sent to the Apache PHP module, but being output as plain text. If someone knows you are running on WordPress they can just go to your wp-config.php and get your MySQL details.
I enjoyed reading your post as I have recently starting hardening my installations. I did however want to contribute a little to points two and three above regarding the Meta Generator tag and RSS Generator tag. Though these two would be the most commonly viewed, the Generator tag also exists in the ATOM, RDF, Comments & Export feeds. There is however a solid and relatively light weight way to disable all Generator outputs. I put together a light weight plugin to handle it, and you can read my post about the process here
Thanks for your input. That is a useful plugin. Those feeds could be easily used to check for version etc.
Actually major concern with wordpress back end is that wp-admin can be hacked easily and i like your tips regarding preventing wp-admin interface.
Thanks alot David..
i guess i found this great article so late just deleted wordpress from my site but now after reading this great security ideas/tips i will re install and secure the site thanks again
Thanks for the tips, I've followed them to the last dot. Let's cross fingers and that b!"£$!!"£ Vietnames hacker leaves me alone...
Great tips, advice and comments, thanks. There's some handy plugins to help with security too - my install procedure is listed at: http://www.abbu.co.uk/how-to-install-wordpress
That's a pretty vital read for anyone new to Wordpress. I find permissions are particularly important. I've found a lot of people I've worked for like to recursively 777 everything so it "works". That's just bad beyond belief.
Yes, it is very tempting to just 777 everything :). I usually do that on localhost as it saves any messing around.
I noticed today that someone, somehow is posting blogs on MY wordpress blog. They are posting items and it shows up as if I posted the item. Any idea how they are doing this and how do I stop it? I have a feeling that one of the social marketing sites that caters to bloggers must have talked me into giving them my info and now they are posting things to my site. I am obviously new at all of this so please be kind. Thank you.
If it is your main blog try changing your WordPress login username and password, your (S)FTP username and password and your database username and password.
If these are seperate blogs that are appearing on subdomains of your main domain, this is because you have WordPress Mu installed. I forget how to stop this. I think you just need to delete a wp-signup.php file or something like that.
You've got a nice list going on here. I'd like a little bit more info on No.8 Moving the config data. Are we to copy OR
Very usefull for every one who use wordpress. Thank you very much.
Great tips, advice and comments, thanks
great info..
thanks for sharing..
at least could have patch some hole.. :)
I've only just set up a Wordpress site and was getting ready to install my theme and make it look pretty, I was looking forward to it... then I started reading about security... worms, sql injection!
I've abandoned the theme install and started looking at how to protect my site.
I've just upgraded to 2.8.5 and will be working through all your suggestion... well at least the ones I can understand.
I'm a newbie to Wordpress and I supose all this security business has disappointed me a little.
Thanks for the tips. I've implemented many of them. I'm having a problem with denying access to wp-includes. It seems that denying access to wp-includes with a rewrite rule in .htaccess causes the post editor to break in the admin area. The Upload/Insert buttons don't work and the Visual editor doesn't show any formatting buttons. Also I get the javascript error "tinymce not defined." It happens in IE8, FF 3.5, Chrome 3.0 and goes away when the rewrite rule is disabled. I haven't tried in other browsers. Has anyone else encountered this and come up with a workaround? I'm using WP 2.8.5. Thanks.
I think WordPress must have changed since I wrote this. I think the editor used to be in the wp-admin folder.
You could just ignore that point. They are pretty gung-ho. IMO, the most important one is to remove the WP identifiers like "Powered by WordPress".