Unfortunately, our blogs are a constant target to comment spammers and hackers. While comment spammers are mostly out to get exposure to their useless links, hackers are notorious for finding and abusing exploits, “defacing” homepages, and compromising configuration files. If you run self-hosted installations of WordPress, or any other kind of content management system for that matter, you are responsible for the security of your sites. You should consider implementing some basic security rules to close the backdoors, and to prevent spammers from wasting your server resources, and slowing down access for your readers.
The first time one of my blogs was hacked, back in 2009, my homepage was defaced. They uploaded some files to my server, and replaced the .htaccess file. Upon entering my homepage, I was welcomed by a hacker who proudly stated he took control over my website. The next hacking was more deceitful since I didn’t noticed it until I visited my own blog through a Google search. When I clicked the listing I was redirected to a complete different website. It turned out that the wp-config.php file was compromised. I was shocked to say the least, but I used this negative experience to my advantage and quickly learned how to properly protect self-hosted blogs on Apache servers. Never again have any of my sites been hacked since I use these security measures and precautions, and the server load reduced noticeable after most spam was blocked in the process as well.
1. File permissions for wp-config.php
Set the file permissions for wp-config.php or any other configuration file to numeric value 600, so that only Owner Permissions is set to read and write. Nobody should be able to touch your configuration file.
2. Never use a default username like Admin or Administrator.
Brute force attacks or exhaustive key searching are strategies that can in theory be used to hack any password. But in order to log in to your administration panel, you will need a combination of username and password to enter. By choosing a different username rather than the default, you reduce the chances of this combination being cracked.
3. Keep your passwords secure
Basic rules to keep in mind when creating a password; Never include terms that are in the dictionary, names, birthdays, events and predictable number sequences. Never use the same hosting or FTP password for your administration panel. Do not store passwords in your FTP client, trojans were found stealing passwords from FTP clients. Preferable use a browser addon such as lastpass to generate very strong passwords, and to securely store them online.
4. Keep your installation up to date.
Always update your plugins and core installation files as soon as new updates are available. Neglecting to do so could leave your installation vulnerable to attacks. I use a WordPress plugin that automatically sends me an email when a new version is available, update notifier.
5. Use plugins or security patches.
For WordPress powered blogs there a number of plugins available to secure your installation. BulletProof Security protects your website from XSS, CSRF, Base64_encode and SQL Injection hacking attempts. Secure WordPress beefs up the security of your WordPress installation by removing error information on login pages, adding blank index files to plugin directories, hiding the WordPress version and much more.
6. Customize your .htaccess file
A customized .htaccess allows you to block referrer spam, content scrapers, proxy users, and it can even be used to block whole ranges of IP addresses that are known to be exploited. Blocking IP addresses and spam referrers is effective, but should be used with caution as it increases the chance of blocking out legitimate visitors!
Here is an example of a custom .htacces file for wordpress that effectively blocks suspicious activity.
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# Blocks direct requests without referrer to comment posts. blocks most automated comment spam.
# ! EDIT YOUR DOMAIN !
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .wp-comments-post\.php*
RewriteCond %{HTTP_REFERER} !.*yourdomain.com.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) http://%{REMOTE_ADDR}/$ [R=301,L]
# Block out any script trying to set a mosConfig value through the URL
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
# Block out any script trying to base64_encode data within the URL
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
# Block out any script that includes a script tag in URL
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
# Block out any script trying to set a PHP GLOBALS variable via URL
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
# Block out any script trying to modify a _REQUEST variable via URL
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
# Return 403 Forbidden header and show the content of the root homepage
RewriteRule . - [F,L]
# SetEnvifNoCase Referrer can be used to block referrer spam. For a list of commonly used spam words see http://codex.wordpress.org/Spam_Words or check your server logs and look for referring spam sites to generate a customized list.
# Keywords example. WARNING, if used improperly you could block legitimate users!
SetEnvIfNoCase Referer "^spamkeyword" spam_ref=1
# Website example:
SetEnvIfNoCase Referer "^http://(www.)?spamdomain.com" spam_ref=1
# Deny access to above spam referrers:
<FilesMatch "(.*)">
Order Allow,Deny
Allow from all
Deny from env=spam_ref
</FilesMatch>
# Block User agents. Most bots you want to block simply ignore the robots.txt file. These rules will deny bad robots, content scrapers, but also proxy browsers.
RewriteCond %{HTTP_USER_AGENT} ^(aesop_com_spiderman|alexibot|backweb|bandit|batchftp|bigfoot) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(black.?hole|blackwidow|blowfish|botalot|buddy|builtbottough|bullseye) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(cheesebot|cherrypicker|chinaclaw|collector|copier|copyrightcheck) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(cosmos|crescent|curl|custo|da|diibot|disco|dittospyder|dragonfly) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(drip|easydl|ebingbong|ecatch|eirgrabber|emailcollector|emailsiphon) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(emailwolf|erocrawler|exabot|eyenetie|filehound|flashget|flunky) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(frontpage|getright|getweb|go.?zilla|go-ahead-got-it|gotit|grabnet) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(grafula|harvest|hloader|hmview|httplib|httrack|humanlinks|ilsebot) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(infonavirobot|infotekies|intelliseek|interget|iria|jennybot|jetcar) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(joc|justview|jyxobot|kenjin|keyword|larbin|leechftp|lexibot|lftp|libweb) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(likse|linkscan|linkwalker|lnspiderguy|lwp|magnet|mag-net|markwatch) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(mata.?hari|memo|microsoft.?url|midown.?tool|miixpc|mirror|missigua) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(mister.?pix|moget|mozilla.?newt|nameprotect|navroad|backdoorbot|nearsite) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(net.?vampire|netants|netcraft|netmechanic|netspider|nextgensearchbot) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(attach|nicerspro|nimblecrawler|npbot|octopus|offline.?explorer) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(offline.?navigator|openfind|outfoxbot|pagegrabber|papa|pavuk) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(pcbrowser|php.?version.?tracker|pockey|propowerbot|prowebwalker) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(psbot|pump|queryn|recorder|realdownload|reaper|reget|true_robot) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(repomonkey|rma|internetseer|sitesnagger|siphon|slysearch|smartdownload) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(snake|snapbot|snoopy|sogou|spacebison|spankbot|spanner|sqworm|superbot) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(superhttp|surfbot|asterias|suzuran|szukacz|takeout|teleport) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(telesoft|the.?intraformant|thenomad|tighttwatbot|titan|urldispatcher) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(turingos|turnitinbot|urly.?warning|vacuum|vci|voideye|whacker) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(libwww-perl|widow|wisenutbot|wwwoffle|xaldon|xenu|zeus|zyborg|anonymouse) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^web(zip|emaile|enhancer|fetch|go.?is|auto|bandit|clip|copier|master|reaper|sauger|site.?quester|whack) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(craftbot|download|extract|stripper|sucker|ninja|clshttp|webspider|leacher|collector|grabber|webpictures).*$ [NC]
RewriteRule . - [F,L]
# Deny access to the .htaccess file
<Files .htaccess>
deny from all
</files>
If you’re site is heavily under attack, or for other reasons, you may want to block a list of IP addresses or a range of IP addresses. It’s even possible to block entire regions of the planet using these ranges. The following resource provides lists of IP ranges that can be used in the htaccess file to deny access. There is a recommended list of exploited servers, and others are available to block countries or regions, such as Eastern Europe, Russia or China.
With these measures in place your blog installation will be a lot more secure. Your site will consume less bandwidth, and access for your readers is optimal. Feel free to post your thoughts and suggestions.