Welcome to the new design! Please report any bugs or issues, thanks :)
Web Dev + WordPress + Security

Secure Visitor Posting for WordPress

Normally, when visitors post a comment to your site, specific types of client data are associated with the request. Commonly, a client will provide a user agent, a referrer, and a host header. When any of these variables is absent, there is good reason to suspect foul play. For example, virtually all browsers provide some sort of user-agent name to identify themselves. Conversely, malicious scripts directly posting spam and other payloads to your site frequently operate without specifying a user agent. In the Ultimate User-Agent Blacklist, we account for the “no-user-agent” case in the very first directive, preventing a host of anonymous visitors from hitting the site.

In addition to empty user-agent strings, malicious requests for site content frequently fail to provide any referrer information. Unless special privacy software is being used, the web page from which a visitor has arrived at your site will be specified in the header information for that request. Likewise, when a visitor posts a comment at your site, the referrer string for that post request will be the URL of that particular page. Thus, as with blank user-agent requests, no-referrer requests are frequently indicative of spam and other malicious behavior.

Another important piece of information provided by all legitimate clients is the host request header. The host header specifies the Internet host and port number of the requested resource. This information is required for all clients making HTTP/1.1 requests. Thus, requiring the host request-header field for all posts to your site safely eliminates illicit requests from hitting your server.

By targeting these three circumstances — blank user agents, empty referrers, and missing host headers — we can greatly improve the overall security of our WordPress-powered sites. Our weapon of choice to forge this server-side strategy is custom set of HTAccess (or httpd.conf) directives:

# WORDPRESS POST SECURITY
<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteCond %{REQUEST_METHOD}  POST
 RewriteCond %{HTTP_REFERER}    !.*perishablepress\.com [NC]
 RewriteCond %{REQUEST_URI}     !.*(wp\-login|wp\-admin|wp\-content|wp\-includes|wp\-trackback).* [NC]
 RewriteCond %{HTTP_USER_AGENT} ^-?$ [OR]
 RewriteCond %{HTTP_REFERER}    ^-?$ [OR]
 RewriteCond %{HTTP_HOST}       ^-?$
 RewriteRule ^(.*)$ - [F,L]
</IfModule>

To implement this HTAccess strategy, replace the domain from “perishablepress.com” to the name of the domain on which these directives operate. To allow multiple domains, replicate the second directive as follows:

RewriteCond %{HTTP_REFERER} !.*domain-01\.tld [NC]
RewriteCond %{HTTP_REFERER} !.*domain-02\.tld [NC]
RewriteCond %{HTTP_REFERER} !.*domain-03\.tld [NC]

After specifying the correct domain information, simply place the code into your site’s root HTAccess file and test for proper functionality. The code itself should be clear, but if something needs explained, please drop a comment and I will do my best to break it on down. And finally, a few obligatory disclaimers:

  • This code works on my server. No guarantees that it will work on yours
  • Blocking blank user agents may result in a small % of false positives
  • Blocking empty referrers may result in a small % of false positives

While this security technique won’t stop all of the bad guys, it will certainly help keep out some of the more obvious offenders. Protecting your site against malicious post requests is an important part of any serious security strategy. Thanks to the magical powers of Apache’s HTAccess directives, we now have a method to secure visitor posting to your WordPress-powered site.

Jeff Starr
About the Author
Jeff Starr = Designer. Developer. Producer. Writer. Editor. Etc.
The Tao of WordPress: Master the art of WordPress.

25 responses to “Secure Visitor Posting for WordPress”

  1. Incettece 2009/08/13 1:45 pm

    What’s up, is there anybody else here?
    If there are any real people here looking to network, leave me a post.
    Oh, and yes I’m a real person LOL.

    Peace,

  2. ordemeded 2009/10/01 8:18 am

    Hi

    I’ve looked a trailer for the “2012”. I was interested in this theme.
    Please advise me a good site on this topic.
    And what do you think about the end of the world 2012.

    Thanks.

  3. Jeff Starr
    Jeff Starr 2009/10/06 9:30 am

    ordemeded, the end of the world is not until the year “2050” — I thought everyone knew that.

    Good luck with your automatic pancake machine.

  4. Zenephype 2009/11/09 2:35 am

    Hello.
    My computer worked not correctly, too much mistakes and buggs. Help me, please to fix errors on my computer.
    My operation system is Windows XP.
    Thx,
    Zenephype

  5. Jeff Starr
    Jeff Starr 2009/11/09 9:48 am

    @Zenephype: Excellent! Glad to be of service – glad to hear you got it working ;)

  6. Jonathan Hollin 2009/11/25 6:40 pm

    Why do you need to explicitly test for an empty referrer? You already test the for condition “referrer does not contain the string perishablepress.com” – surely an empty referrer matches that test and thus need not be separately tested?

  7. Jeff Starr

    @Jonathan Hollin: good point! Thanks for pointing that out :)

  8. poessypen 2010/02/26 7:21 am

    Hi,

    New here. Got a question about this new kitten. Well, actually Ms. Boots had five kittens.

    My wife gave all except one of them away. She says she gets to name it, I say I do because I clean out the liter box. haha

    Any good websites for finding cat names?

    thanks

  9. Jeff Starr

    I think literbox.com might be useful for you. haha

  10. Hi Jeff.

    Amazing blog you run here, thank you.

    I don’t know wordpress’ files all that well, but I think the wp-trackback.php file might need to be included in the whitelist as well as it also works with POST.

    Regards

  11. Jeff Starr

    @Abraham: Good call – I updated the code to allow requests for “wp-trackback.php” Thanks :)

  12. I have been getting a hell of a lot of what seems like human spam to me.

    That is people being paid to spam.

    Pretty damn annoying I say.

    Any idea how you block that shit?

    Anyway thanks for the security start.

Comments are closed for this post. Something to add? Let me know.
Welcome
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
Blackhole Pro: Trap bad bots in a virtual black hole.
Thoughts
Playing the long game.
They have weaponized the idiots.
Good software never steals focus from the user. Even during startup.
After 10 years running my own business, I still manage schedules and tasks using old school post-it notes, sometimes simple sometimes very elaborate.
You know those sites, where you're trying to just grab a quick bit of information but the page is shifting all over the place as it loads up 3 million advertisements.
Selling two of my top WordPress domains, wp-zen.com & zen-wp.com $300 for both. Aged 9 years. Drop a line if interested.
Never force your users to type out a password (or any long string of characters) by blocking the paste function. Typing long strings leads to MORE errors than simple copy/paste.