Bad Behavior 1.0-rc1

April 24th, 2005 by Michael Hampton

Bad Behavior Bad Behaviour

See also the blog entry announcing Bad Behavior 1.0-rc2.

Have you got anything without spam?

Gone over your bandwidth quota this month? Had to upgrade your web hosting plan? Who’s visiting your site so much? It’s those pesky spambots. They suck down your web pages repeatedly looking for links to post blog spam to, and email addresses to send conventional spam to. And then they come back the next day for more.

There has been no good way to sort out the spambots from the real users, since most of the spambots pretend to be real users. Until now.

Bad Behavior

Bad Behavior analyzes incoming requests to your server. If they match a profile of a known spambot, the spammer gets a nice error message instead of your blog.

While Bad Behavior has been tested extensively prior to this release, it is possible that there are still bugs. It’s possible that a spambot might slip through the cracks somewhere, and it’s possible that a human might be misidentified as a spambot. (They’ll get an error message explaining the situation and giving possible solutions.) If this happens please let me know so I can fix it!

Installation and Usage

Bad Behavior works as a WordPress plugin. Install it in the usual way: unzip the file and upload the bad-behavior directory to wp-content/plugins. Before running it, you may want to customize some of the variables in bad-behavior/bad-behavior-wordpress-plugin.php.

Bad Behavior can also be customized for other PHP-based software; see the bad-behavior/bad-behavior-generic.php file to get started. It will provide basic spambot blocking out of the box, but it won’t be able to keep logs (or later, some more advanced stuff) unless it’s customized to your particular PHP-based software. Just require_once("bad-behavior/bad-behavior-generic.php"); somewhere in your common PHP code to use it this way.

Thanks!

Special thanks to Mark Jaquith, Firas Durri and many others in #wordpress who assisted greatly in shaking loose and squashing many, many bugs, as well as making the code a little friendlier, before this initial release.


23 Responses to “Bad Behavior 1.0-rc1”

  1. 1

    Denis de Bernardy Says

    Just curious: How well does the plugin play with advanced cache?

  2. 2

    T. Testuser Says

    This looks very promising. Just wanted to check something before trying it… you say the current version is 1.0-rc1, yet it comes up in the plugin manager as 0.9.1. The heading in bad-behavior-wordpress-plugin.php also says 0.9.1. Did you possibly forget to update the zip-file or something?
    I apologize if there is an obvious Unixy programmerish answer to this that everyone understands except me.

  3. 3

    Michael Hampton Says

    Hmm. Good question, Denis. When WP-Cache serves a static page, no WordPress plugins are loaded, the database is not opened, etc. So Bad Behavior gets no chance to run. The good news is, Bad Behavior can still protect your static pages served by WP-Cache, but it will not be able to write logs to the database. To enable Bad Behavior with WP-Cache, add the following line in wp-content/advanced-cache.php. It should be placed around line 93:

    require_once('plugins/bad-behavior/bad-behavior-generic.php');

    The new code, once complete, should read (lines 92-94):

    if ($mtime + $cache_max_time > time() + $cache_time_rnd) {
            require_once('plugins/bad-behavior/bad-behavior-generic.php');
            $meta = new CacheMeta;

    This makes a fairly good example of how Bad Behavior can be integrated easily into just about any PHP-based software.

  4. 4

    Michael Hampton Says

    No, the version number is right. 1.0-rc1 shows as 0.9.1 in the plugin manager and at wp-plugins.net. The Unixy programmerish answer is that wp-plugins.net doesn’t care much for letters in the version number. :-)

  5. 5

    Kyle Says

    This looks pretty cool. What sort of things about the request are you analyzing, and do you have a rough idea of the peformance hit a site will take with this plugin?

  6. 6

    Denis de Bernardy Says

    thanks for the howto for making it work with wp-cache.

    I’ve also got a tiny feature/optimization request. I noticed while tracing your queries that the plugin does two round-trips to the server before the page loads:

    - on the one side, you’ve got a DB table creation query
    - on the other, you’ve got a DB cleanup query

    i suspect you could register both at shutdown rather than doing them before the page loads to the user.

    Else, it looks wonderfully useful. Combined a referral spam plugin (would it even be useful in your opinion?), this is likely to be good enough for me to move ahead with an automated backlink discovery plugin idea I’ve in mind. :)

  7. 7

    Frank Says

    Sorry, you lost me.
    I can’t find “wp-content/advanced-cache.php”
    there is no single-file in my wp-content / 1.5.
    what can I do now to use Bad behaviour ?

  8. 8

    Frank Says

    And where can I get THAT cute plug you use here
    (to submit a mail, copy the code….)

  9. 9

    Michael Hampton Says

    Kyle, the performance impact should be minimal, even with DB logging. See the FAQ.

    Denis, thanks for the feedback. I’ve tried to avoid actually hooking into WP anywhere, preferring to do everything up-front. For requests which are blocked, hooking into shutdown is not feasible, but for requests which are allowed through, it could be done. I’ll consider this for a future version. As for referrer spam, Bad Behavior has proven quite useful in blocking referrer spam already, but a little extra protection never hurts!

    Frank, you don’t need the hack in comment 6 unless you’re running WP-Cache, which it appears you are not. Just install Bad Behavior normally.

  10. 10

    Denis de Bernardy Says

    actually, the hack in comment 6 fails miserably because of stream errors.

    the correct method is to modify the index.php file of your site. assuming you are also using referrer karma, it will thus read:

    require_once(‘wp-content/plugins/bad-behavior/bad-behavior-generic.php’);
    require_once (‘wp-content/referrer-karma.php’);
    check_referrer();
    /* Short and sweet */
    define(‘WP_USE_THEMES’, true);
    require(‘./wp-blog-header.php’);

  11. 11

    Denis de Bernardy Says

    I presume that enabling the plugin thereafter is redundant?

  12. 12

    Michael Hampton Says

    Denis, indeed, enabling the plugin after that is completely redundant, and you should leave it disabled if you install Bad Behavior in that manner, or you will get errors. I’ll have to look at WP-Cache again; the code I posted seems like it should work.

    Podz also posted a solution based on .htaccess which might be helpful to some people.

  13. 13

    ricardo galli Says

    To #6 and others regarding making it work with Wp-cache.

    Are you sure you cannot do it by inserting the following tags in your plugin?

    <!–mclude some.php–>
    < ?php require(’some.php’); ?>
    <!–/mclude–>

    BTW wp-cache will [only] always execute “some.php”.

  14. 14

    Denis de Bernardy Says

    I think the problem from solution at #6 came from the require being inside a class declaration. I’ve had a wide variety of bugs trying things such as this in php in the past.

    I’ll likely stick to the index.php solution or try Podz’ .htaccess solution. No need to let ref karma hog resources for something that shouldn’t even make a hit in the first place.

  1. 1

    Wordpress Plugin Competition Blog

  2. 2

    Weblog Tools Collection » WP Plugin: Bad Behavior

  3. 3

    ПиÑ?карање » Ð?рхива блога » Ð?еприÑ?тојно понашање

  4. 4

    incorporated subversion » Archive » WordPress plugins ahoy

  5. 5

    IO ERROR

  6. 6

    Spontaneous Monotony » Blog Archive » Bad Behaviour will be dealt with

  7. 7

    Punishing Bad Behavior - IO ERROR

  8. 8

    Spontaneous Monotony » Blog Archive » Anti-spam plugins

  9. 9

    Lunacy Unleashed » Bad Behavior 2 Alpha 2