Bad Behavior


 


Bad Behavior is a set of PHP scripts which prevents spambots from accessing your site by analyzing their actual HTTP requests and comparing them to profiles from known spambots. It goes far beyond User-Agent and Referer, however. Bad Behavior is available for several PHP-based software packages, and also can be integrated in seconds into any PHP script. (quote from the homepage).

Integration in wikka


Bad-Behavior 1.2.x series

these instructions are for version 1.2.1 but should work for the whole 1.2.x series

1. download it
2. unzip the file, go into the folder and make the following changes:
3. add bad-behavior-wikkawiki.php to the folder, with the following content:
  1. <?php
  2. /*
  3. http://www.ioerror.us/software/bad-behavior/
  4.  
  5. Bad Behavior - detects and blocks unwanted Web accesses
  6. Copyright (C) 2005 Michael Hampton
  7.  
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12.  
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with this program; if not, write to the Free Software
  20. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22.  
  23. /**
  24.  * Entry point for using bad behavior with wikkawiki.
  25.  *
  26.  * @author: {@link http://www.ioerror.us/software/bad-behavior/ Michael Hampton} (generic entry file)
  27.  * @author: {@link http://wikka.jsnx.com/NilsLindenberg Nils Lindenberg} (rewritten for wikka)
  28.  * @author: {Stefan Lindenberg} (simplification of the code)
  29.  *
  30.  * @version: 1.2
  31.  */
  32.  
  33.  
  34. //***Configuration***
  35.  
  36. // The database table name to use.
  37. define('WP_BB_LOG', $wakka->config['table_prefix'].'bad_behavior_log');
  38.  
  39. define('WP_BB_CWD', dirname(__FILE__));
  40.  
  41. // Log failed requests to the database.
  42. if ($wakka->config['bad-behavior-logging'] == 1) $wp_bb_logging = TRUE;
  43. else $wp_bb_logging = TRUE;
  44.  
  45. // Log all requests to the database, not just failed requests.
  46. if ($wakka->config['bad-behavior-logging'] == 2) $wp_bb_verbose_logging = TRUE;
  47. else $wp_bb_verbose_logging = FALSE;
  48.  
  49. // How long to keep the logs around (in days).
  50. $wp_bb_logging_duration = 7;
  51.  
  52. // Email address to contact you in case of problems
  53. // This will be shown to users on the error page, which means it will
  54. // be exposed to spammers! Bad Behavior will munge it automatically; you
  55. // should NOT munge it here!
  56. $wp_bb_email = $wakka->config['admin_email'];
  57.  
  58.  
  59. //***Callbacks***
  60.  
  61. // return a UTC date in the format preferred by your database
  62. function wp_bb_date() {
  63.     return gmdate('Y-m-d H:i:s');
  64. }
  65.  
  66. // run a SQL query and return # of rows affected, or FALSE if query failed
  67. function wp_bb_db_query($query) {
  68.     global $wakka;
  69.  
  70.     $result = $wakka->Query($query);
  71.     if ($result === TRUE || $result === FALSE) $returnValue = $result;
  72.          else {
  73.             $data = mysql_fetch_row($result);
  74.         $query_parts = explode(" ",$query);
  75.         $mysql_statement = strtolower($query_parts[0]);
  76.         switch ($mysql_statement) {
  77.                      case "insert":
  78.                      case "delete":
  79.                      case "update":
  80.                              $returnValue = mysql_num_rows($result);
  81.                              break;
  82.                      case "select":
  83.                              $returnValue = mysql_affected_rows();
  84.                              break;
  85.                           default:
  86.                                   if($data === FALSE) $returnValue = 0;
  87.                  else $returnValue = 1;
  88.                  }
  89.                  mysql_free_result($result);
  90.     }
  91.          return $returnValue;
  92. }
  93.  
  94. // Load core functions and do initial checks
  95. require_once(WP_BB_CWD . "/bad-behavior-core.php");
  96.  
  97. ?>


4. install the mysql-table (replace wikka_ in the first line with your table-prefix - must be the same as in the wikka.config!) :

CREATE TABLE IF NOT EXISTS wikka_bad_behavior(
`id` int( 11 ) NOT NULL AUTO_INCREMENT ,
`ip` text NOT NULL ,
`date` datetime NOT NULL default '0000-00-00 00:00:00',
`request_method` text NOT NULL ,
`http_host` text,
`request_uri` text NOT NULL ,
`server_protocol` text NOT NULL ,
`http_referer` text,
`http_user_agent` text,
`http_headers` text NOT NULL ,
`request_entity` text NOT NULL ,
`denied_reason` text NOT NULL ,
`http_response` int( 3 ) NOT NULL ,
PRIMARY KEY ( `id` )
)


5. upload the whole folder to 3rdparty/plugins/bad-behavior/

6. add the following line to wikka.php
//load 'bad-behavior'
if ($wakka->config['bad-behavior'] == 1) require_once("3rdparty/plugins/bad-behavior/bad-behavior-wikkawiki.php");


=> right before the
  1. // go !



Configuration


add
    'bad-behavior' => '1',
    'bad-behavior-logging' => '1',


to your wikka.config.php

bad-behavior:

bad-behavior-logging

Bad Behavior 2.0.x series

note: this is a it's-working-for-me, i.e. an alpha version.



2. extract the zip-file and upload the content of the subfolder bad-behavior (i.e from admin.inc.php to whitelist.inc.php) to 3rdparty/plugins/bad-behavior

3. Add the following file as bad-behavior-wikkawiki.php to the same folder:

  1. <?php
  2. /**
  3.  * Contains the functions and config entries needed by Bad Behavior 2.
  4.  *
  5.  * Only this file should be used as an entry point from within wikkawiki.
  6.  * It is based on the generic file of Bad Behavior 2.x and has been adjusted for the use with wikkawiki.
  7.  *
  8.  * @package     3rdparty
  9.  * @subpackage  Bad Behavior
  10.  * @version     $Id$
  11.  * @filesource
  12.  *  
  13.  * @author      {@link http://www.bad-behavior.ioerror.us/ Michael Hampton} (generic entry file)
  14.  * @author      {@link http://www.wikkawiki.org/NilsLindenberg Nils Lindenberg} (adjusted for wikkawiki)
  15.  * @license     http://www.gnu.org/copyleft/gpl.html GNU General Public License
  16.  *
  17.  */
  18.  
  19. /*
  20. Bad Behavior - detects and blocks unwanted Web accesses
  21. Copyright (C) 2005-2006 Michael Hampton
  22.  
  23. This program is free software; you can redistribute it and/or modify
  24. it under the terms of the GNU General Public License as published by
  25. the Free Software Foundation; either version 2 of the License, or
  26. (at your option) any later version.
  27.  
  28. As a special exemption, you may link this program with any of the
  29. programs listed below, regardless of the license terms of those
  30. programs, and distribute the resulting program, without including the
  31. source code for such programs: ExpressionEngine
  32.  
  33. This program is distributed in the hope that it will be useful,
  34. but WITHOUT ANY WARRANTY; without even the implied warranty of
  35. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  36. GNU General Public License for more details.
  37.  
  38. You should have received a copy of the GNU General Public License
  39. along with this program; if not, write to the Free Software
  40. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  41.  
  42. Please report any problems to badbots AT ioerror DOT us
  43. */
  44.  
  45. /**
  46.  * Hold the directory of Bad Behavior 2 to protect it from being called directly.
  47.  */
  48. define('BB2_CWD', dirname(__FILE__).DIRECTORY_SEPARATOR);
  49.  
  50. /**
  51.  * Hold Bad Behavior Settings.
  52.  */
  53. $bb2_settings_defaults = array(
  54.     'log_table' => $wakka->GetConfigValue('table_prefix').'bad_behavior',
  55.     'display_stats' => true,
  56.     'strict' => false,
  57.     'verbose' => false
  58. );
  59.  
  60. // Bad Behavior callback functions.
  61.  
  62. /**
  63.  * Return current time.
  64.  *
  65.  * @return string current time in MySQL format.
  66.  */
  67. function bb2_db_date() {
  68.     return gmdate('Y-m-d H:i:s');
  69. }
  70.  
  71. /**
  72.  * Return affected rows from most recent query.
  73.  *
  74.  * not used.
  75.  *
  76.  * @return int number of affected rows from most recent query.
  77.  * @todo    write function.
  78.  */
  79. function bb2_db_affected_rows() {
  80.     //return $this->getAffectedRows();
  81.     print "bb2_db_affected_rows";
  82. }
  83.  
  84. /**
  85.  * Escape a string for database usage.
  86.  *
  87.  * @param   string $string mandatory: string to be escaped.    
  88.  * @return string MySQL escaped string.
  89.  */
  90. function bb2_db_escape($string) {
  91.     return mysql_real_escape_string($string);
  92. }
  93.  
  94. /**
  95.  * Return the number of rows in a particular query.
  96.  *
  97.  * @return  int number of row
  98.  */
  99. function bb2_db_num_rows($result) {
  100.     if ($result !== FALSE)
  101.         return count($result);
  102.     return 0;
  103. }
  104.  
  105. /**
  106.  * Run a query and return the results, if any.
  107.  *
  108.  * Bad Behavior will use the return value here in other callbacks.
  109.  * Due to Wakka::Query() stopping in case of an error this will never return false.
  110.  *
  111.  * @uses    Wakka::Query()
  112.  * @param   string $query mandatory: MySQL-Query to be executed.
  113.  * @return  mixed result of the query.
  114.  */
  115. function bb2_db_query($query) {
  116.     global $wakka;
  117.     return $wakka->Query($query);
  118. }
  119.  
  120. /**
  121.  * Return all rows in a particular query.
  122.  *
  123.  * Should contain an array of all rows generated by calling mysql_fetch_assoc()
  124.  * or equivalent and appending the result of each call to an array.
  125.  *
  126.  * Not used.
  127.  */
  128. function bb2_db_rows($result) {
  129.     while ($row = mysql_fetch_assoc($result)) $return[] = $row;
  130.    
  131.     mysql_free_result($result);
  132.     return $return;
  133. }
  134.  
  135. /**
  136.  * Return emergency contact email address.
  137.  *
  138.  * @see     wikka.config.php
  139.  * @uses    Config::$admin_email
  140.  * @uses    Wakka::GetConfigValue()
  141.  * @return  string email adress of wikka admin 
  142.  */
  143. function bb2_email() {
  144.     global $wakka;
  145.     return $wakka->GetConfigValue('admin_email');
  146. }
  147.  
  148. /**
  149.  * Retrieve Bad Behavior 2 settings.
  150.  *
  151.  * Hardcoded in this file (see above)
  152.  * @return  array settings for bb2
  153.  */
  154. function bb2_read_settings() {
  155.     global $bb2_settings_defaults;
  156.     return $bb2_settings_defaults;
  157. }
  158.  
  159. /**
  160.  * Write settings to database.
  161.  *
  162.  * Not used.
  163.  * @return boolean FALSE
  164.  */
  165. function bb2_write_settings($settings) {
  166.     return false;
  167. }
  168.  
  169. /**
  170.  * Install Bad Behavior 2.
  171.  *
  172.  * Not used, we'll use wikka-installer instead.
  173.  *
  174.  * @return  boolean FALSE
  175.  */
  176. function bb2_install() {
  177.     return false;
  178. }
  179.  
  180. /**
  181.  * Insert the javascript for the Screener into a html file.
  182.  *
  183.  * This is optional we'll fall back to cookies if you don't use it.
  184.  */
  185. function bb2_insert_head() {
  186.     global $bb2_javascript;
  187.     echo $bb2_javascript;
  188. }
  189.  
  190. /**
  191.  * Display stats (enabled by default).
  192.  *
  193.  * Used by {{badbehavior}} action.
  194.  */  
  195. function bb2_insert_stats($force = false) {
  196.     $settings = bb2_read_settings();
  197.  
  198.     if ($force || $settings['display_stats']) {
  199.         $blocked = bb2_db_query("SELECT COUNT(*) FROM " . $settings['log_table'] . " WHERE `key` NOT LIKE '00000000'");
  200.         if ($blocked !== FALSE) {
  201.             return(sprintf('<p><a href="http://www.homelandstupidity.us/software/bad-behavior/">%1$s</a> %2$s <strong>%3$s</strong> %4$s</p>', __('Bad Behavior'), __('has blocked'), $blocked[0]["COUNT(*)"], __('access attempts in the last 7 days.')));
  202.         }
  203.         else return('Nobody blocked yet.');
  204.     }
  205.     else return('The display of Bad Behavior stats has been turned off.');
  206. }
  207.  
  208. /**
  209.  * Return the top-level relative path of wherever we are (for cookies).
  210.  */
  211. function bb2_relative_path() {
  212.     global $wakka;
  213.     return $wakka->GetConfigValue("base_url");
  214. }
  215.  
  216. // Calls inward to Bad Behavor itself.
  217. require_once(BB2_CWD . "version.inc.php");
  218. require_once(BB2_CWD . "core.inc.php");
  219. //bb2_install();
  220.  
  221. bb2_start(bb2_read_settings());
  222.  
  223. ?>


4. install the mysql-table (replace wikka_ in the first line with your table-prefix - must be the same as in the wikka.config!) :
CREATE TABLE IF NOT EXISTS wikka_bad_behavior (
		`id` INT(11) NOT NULL auto_increment,
		`ip` TEXT NOT NULL,
		`date` DATETIME NOT NULL default '0000-00-00 00:00:00',
		`request_method` TEXT NOT NULL,
		`request_uri` TEXT NOT NULL,
		`server_protocol` TEXT NOT NULL,
		`http_headers` TEXT NOT NULL,
		`user_agent` TEXT NOT NULL,
		`request_entity` TEXT NOT NULL,
		`key` TEXT NOT NULL,
		INDEX (`ip`(15)),
		INDEX (`user_agent`(10)),
		PRIMARY KEY (`id`) );


5. edit actions/header.php and add the following line:
  1.     <?php bb2_insert_head(); #BB2 ?>


behind

  1.     <base href="<?php echo $site_base ?>" />


6. edit wikka.php and add the following line:

  1. require_once('3rdparty/plugins/bad-behavior/bad-behavior-wikkawiki.php'); #BB2 


before the
  1. /**
  2.  * Run the engine.
  3.  */


Issues


CategoryDevelopment3rdParty CategoryDevelopmentAntiSpam
Comments
Comment by DarTar
2005-06-06 10:25:16
Nils, you might want to add a config option check to enable/disable it.
Comment by EndreAdolfsen
2006-03-30 10:36:41
I just installed this, curious to see the effect I must admit :)
Comment by NilsLindenberg
2006-03-30 11:47:49
Depends on how much spam you got before. If it wasn't much before bb won't have to stop much
Comment by EndreAdolfsen
2006-03-30 11:50:18
It hasn't been a problem, but it's been increasing. I've got mods to deal with it too, but any automatic help will do. I¨'ll report back in a while when I see the results.
Comment by 65.13.28.116
2006-04-15 23:00:52
It would be nice to have a Bad Behavior log reader plugin like this for Wikka:
http://www.elvery.net/drzax/?p=128
Comment by DarTar
2006-04-16 10:10:19
This is something for Nils... ;)
Comment by 65.13.28.116
2006-04-16 22:22:31
I am really impressed with Bad Behavior. Before installation I was getting 5 - 10 spam comments on my Wiki daily. Now it has dropped to ZERO! This is a must-have plugin for sure.
Comment by NilsLindenberg
2006-04-18 11:46:27
>It would be nice to have a Bad Behavior log reader plugin like this for Wikka:
> http://www.elvery.net/drzax/?p=12

Thanks for the link but don't expect it too soon.
Comment by XyzzyB
2006-07-25 17:54:23
This doesn't work for me. Errors follow:

Warning: require_once(/[server]/wiki.xyzzyb.com/3rdparty/plugins/bad-behavior/bad-behavior-core.php) [function.require-once]: failed to open stream: No such file or directory in /[server]/wiki.xyzzyb.com/3rdparty/plugins/bad-behavior/bad-behavior-wikkawiki.php on line 95

Fatal error: require_once() [function.require]: Failed opening required '/[server]/wiki.xyzzyb.com/3rdparty/plugins/bad-behavior/bad-behavior-core.php' (include_path='.:/usr/local/php5/lib/php') in /[server]/wiki.xyzzyb.com/3rdparty/plugins/bad-behavior/bad-behavior-wikkawiki.php on line 95

It seems that bad-behavior-wikkawiki.php wants to be in a lower directory (not with all the other web service files such as bad-behavior-wordpress.php), so I moved it so that it was with the core files.

Warning: require_once(/[server]/wiki.xyzzyb.com/3rdparty/plugins/bad-behavior/bad-behavior-core.php) [function.require-once]: failed to open stream: No such file or directory in /[server]/wiki.xyzzyb.com/3rdparty/plugins/bad-behavior/bad-behavior-wikkawiki.php on line 95

Fatal error: require_once() [function.require]: Failed opening required '/[server]/wiki.xyzzyb.com/3rdparty/plugins/bad-behavior/bad-behavior-core.php' (include_path='.:/usr/local/php5/lib/php') in /[server]/wiki.xyzzyb.com/3rdparty/plugins/bad-behavior/bad-behavior-wikkawiki.php on line 95

The bad-behavior plugin has a core.inc.php, but now bad-behavior-core.php. If I rename core.inc.php I get "I said no cheating!" on all wiki pages.
Comment by NilsLindenberg
2006-08-02 19:14:57
XyzzyB, which version of bad behaviour did you use? This code will work with the outdated 1.2.1 but has not been test for the 2.0.x series
Comment by MikeRoddewig
2006-10-16 11:55:36
I coded up a script for 2.2.1 which appears to work but I don't get any comment spam (yet). Get it at [[http://www.roddefig.org/wikka.php?wakka=BadBehavior]] Suggestions/improvements/comments would all be appreciated.
Comment by SimonFinch
2007-01-03 08:45:51
Really excellent - thank you. I was receiving a LOT of spam comments - after implementing this I'm down to zero. Note you can no longer download version 1.2.1 of Bad behaviour from their site .. but version 1.2.4 works just fine.
Comment by NilsLindenberg
2007-02-04 14:46:49
I should have read the comment of MikeRoddewig beforehand, would probably have saved me time :)
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki