PageRenderTime 39ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/sources/ext/bad-behavior/bad-behavior/core.inc.php

https://github.com/Arantor/Elkarte
PHP | 224 lines | 167 code | 25 blank | 32 comment | 65 complexity | eae339e606c925755b0be846a3ea2e4d MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-3.0
  1. <?php if (!defined('BB2_CWD')) die("I said no cheating!");
  2. define('BB2_VERSION', "2.2.13");
  3. // Bad Behavior entry point is bb2_start()
  4. // If you're reading this, you are probably lost.
  5. // Go read the bad-behavior-generic.php file.
  6. define('BB2_CORE', dirname(__FILE__));
  7. define('BB2_COOKIE', 'bb2_screener_');
  8. require_once(BB2_CORE . "/functions.inc.php");
  9. // Kill 'em all!
  10. function bb2_banned($settings, $package, $key, $previous_key=false)
  11. {
  12. // Some spambots hit too hard. Slow them down a bit.
  13. sleep(2);
  14. require_once(BB2_CORE . "/banned.inc.php");
  15. bb2_display_denial($settings, $package, $key, $previous_key);
  16. bb2_log_denial($settings, $package, $key, $previous_key);
  17. if (is_callable('bb2_banned_callback')) {
  18. bb2_banned_callback($settings, $package, $key);
  19. }
  20. // Penalize the spammers some more
  21. bb2_housekeeping($settings, $package);
  22. die();
  23. }
  24. function bb2_approved($settings, $package)
  25. {
  26. // Dirk wanted this
  27. if (is_callable('bb2_approved_callback')) {
  28. bb2_approved_callback($settings, $package);
  29. }
  30. // Decide what to log on approved requests.
  31. if (($settings['verbose'] && $settings['logging']) || empty($package['user_agent'])) {
  32. bb2_db_query(bb2_insert($settings, $package, "00000000"));
  33. }
  34. }
  35. # If this is reverse-proxied or load balanced, obtain the actual client IP
  36. function bb2_reverse_proxy($settings, $headers_mixed)
  37. {
  38. # Detect if option is on when it should be off
  39. $header = uc_all($settings['reverse_proxy_header']);
  40. if (!array_key_exists($header, $headers_mixed)) {
  41. return false;
  42. }
  43. $addrs = @array_reverse(preg_split("/[\s,]+/", $headers_mixed[$header]));
  44. # Skip our known reverse proxies and private addresses
  45. if (!empty($settings['reverse_proxy_addresses'])) {
  46. foreach ($addrs as $addr) {
  47. if (!match_cidr($addr, $settings['reverse_proxy_addresses']) && !is_rfc1918($addr)) {
  48. return $addr;
  49. }
  50. }
  51. } else {
  52. foreach ($addrs as $addr) {
  53. if (!is_rfc1918($addr)) {
  54. return $addr;
  55. }
  56. }
  57. }
  58. # If we got here, someone is playing a trick on us.
  59. return false;
  60. }
  61. // Let God sort 'em out!
  62. function bb2_start($settings)
  63. {
  64. // Gather up all the information we need, first of all.
  65. $headers = bb2_load_headers();
  66. // Postprocess the headers to mixed-case
  67. // TODO: get the world to stop using PHP as CGI
  68. $headers_mixed = array();
  69. foreach ($headers as $h => $v) {
  70. $headers_mixed[uc_all($h)] = $v;
  71. }
  72. // IPv6 - IPv4 compatibility mode hack
  73. $_SERVER['REMOTE_ADDR'] = preg_replace("/^::ffff:/", "", $_SERVER['REMOTE_ADDR']);
  74. // Reconstruct the HTTP entity, if present.
  75. $request_entity = array();
  76. if (!strcasecmp($_SERVER['REQUEST_METHOD'], "POST") || !strcasecmp($_SERVER['REQUEST_METHOD'], "PUT")) {
  77. foreach ($_POST as $h => $v) {
  78. $request_entity[$h] = $v;
  79. }
  80. }
  81. $request_uri = $_SERVER["REQUEST_URI"];
  82. if (!$request_uri) $request_uri = $_SERVER['SCRIPT_NAME']; # IIS
  83. if ($settings['reverse_proxy'] && $ip = bb2_reverse_proxy($settings, $headers_mixed)) {
  84. $headers['X-Bad-Behavior-Remote-Address'] = $_SERVER['REMOTE_ADDR'];
  85. $headers_mixed['X-Bad-Behavior-Remote-Address'] = $_SERVER['REMOTE_ADDR'];
  86. } else {
  87. $ip = $_SERVER['REMOTE_ADDR'];
  88. }
  89. @$package = array('ip' => $ip, 'headers' => $headers, 'headers_mixed' => $headers_mixed, 'request_method' => $_SERVER['REQUEST_METHOD'], 'request_uri' => $request_uri, 'server_protocol' => $_SERVER['SERVER_PROTOCOL'], 'request_entity' => $request_entity, 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'is_browser' => false,);
  90. $result = bb2_screen($settings, $package);
  91. if ($result && !defined('BB2_TEST')) bb2_banned($settings, $package, $result);
  92. return $result;
  93. }
  94. function bb2_screen($settings, $package)
  95. {
  96. // Please proceed to the security checkpoint, have your identification
  97. // and boarding pass ready, and prepare to be nakedized or fondled.
  98. // CloudFlare-specific checks not handled by reverse proxy code
  99. // Thanks to butchs at Simple Machines
  100. if (array_key_exists('Cf-Connecting-Ip', $package['headers_mixed'])) {
  101. require_once(BB2_CORE . "/cloudflare.inc.php");
  102. $r = bb2_cloudflare($package);
  103. if ($r !== false && $r != $package['ip']) return $r;
  104. }
  105. // First check the whitelist
  106. require_once(BB2_CORE . "/whitelist.inc.php");
  107. if (!bb2_run_whitelist($package)) {
  108. // Now check the blacklist
  109. require_once(BB2_CORE . "/blacklist.inc.php");
  110. if ($r = bb2_blacklist($package)) return $r;
  111. // Check the http:BL
  112. require_once(BB2_CORE . "/blackhole.inc.php");
  113. if ($r = bb2_httpbl($settings, $package)) {
  114. if ($r == 1) return false; # whitelisted
  115. return $r;
  116. }
  117. // Check for common stuff
  118. require_once(BB2_CORE . "/common_tests.inc.php");
  119. if ($r = bb2_protocol($settings, $package)) return $r;
  120. if ($r = bb2_cookies($settings, $package)) return $r;
  121. if ($r = bb2_misc_headers($settings, $package)) return $r;
  122. // Specific checks
  123. @$ua = $package['user_agent'];
  124. // Search engine checks come first
  125. if (stripos($ua, "bingbot") !== FALSE || stripos($ua, "msnbot") !== FALSE || stripos($ua, "MS Search") !== FALSE) {
  126. require_once(BB2_CORE . "/searchengine.inc.php");
  127. if ($r = bb2_msnbot($package)) {
  128. if ($r == 1) return false; # whitelisted
  129. return $r;
  130. }
  131. return false;
  132. } elseif (stripos($ua, "Googlebot") !== FALSE || stripos($ua, "Mediapartners-Google") !== FALSE || stripos($ua, "Google Web Preview") !== FALSE) {
  133. require_once(BB2_CORE . "/searchengine.inc.php");
  134. if ($r = bb2_google($package)) {
  135. if ($r == 1) return false; # whitelisted
  136. return $r;
  137. }
  138. return false;
  139. } elseif (stripos($ua, "Yahoo! Slurp") !== FALSE || stripos($ua, "Yahoo! SearchMonkey") !== FALSE) {
  140. require_once(BB2_CORE . "/searchengine.inc.php");
  141. if ($r = bb2_yahoo($package)) {
  142. if ($r == 1) return false; # whitelisted
  143. return $r;
  144. }
  145. return false;
  146. } elseif (stripos($ua, "Baidu") !== FALSE) {
  147. require_once(BB2_CORE . "/searchengine.inc.php");
  148. if ($r = bb2_baidu($package)) {
  149. if ($r == 1) return false; # whitelisted
  150. return $r;
  151. }
  152. return false;
  153. }
  154. // MSIE checks
  155. if (stripos($ua, "; MSIE") !== FALSE) {
  156. $package['is_browser'] = true;
  157. require_once(BB2_CORE . "/browser.inc.php");
  158. if (stripos($ua, "Opera") !== FALSE) {
  159. if ($r = bb2_opera($package)) return $r;
  160. } else {
  161. if ($r = bb2_msie($package)) return $r;
  162. }
  163. } elseif (stripos($ua, "Konqueror") !== FALSE) {
  164. $package['is_browser'] = true;
  165. require_once(BB2_CORE . "/browser.inc.php");
  166. if ($r = bb2_konqueror($package)) return $r;
  167. } elseif (stripos($ua, "Opera") !== FALSE) {
  168. $package['is_browser'] = true;
  169. require_once(BB2_CORE . "/browser.inc.php");
  170. if ($r = bb2_opera($package)) return $r;
  171. } elseif (stripos($ua, "Safari") !== FALSE) {
  172. $package['is_browser'] = true;
  173. require_once(BB2_CORE . "/browser.inc.php");
  174. if ($r = bb2_safari($package)) return $r;
  175. } elseif (stripos($ua, "Lynx") !== FALSE) {
  176. $package['is_browser'] = true;
  177. require_once(BB2_CORE . "/browser.inc.php");
  178. if ($r = bb2_lynx($package)) return $r;
  179. } elseif (stripos($ua, "MovableType") !== FALSE) {
  180. require_once(BB2_CORE . "/movabletype.inc.php");
  181. if ($r = bb2_movabletype($package)) return $r;
  182. } elseif (stripos($ua, "Mozilla") !== FALSE && stripos($ua, "Mozilla") == 0) {
  183. $package['is_browser'] = true;
  184. require_once(BB2_CORE . "/browser.inc.php");
  185. if ($r = bb2_mozilla($package)) return $r;
  186. }
  187. // More intensive screening applies to POST requests
  188. if (!strcasecmp('POST', $package['request_method'])) {
  189. require_once(BB2_CORE . "/post.inc.php");
  190. if ($r = bb2_post($settings, $package)) return $r;
  191. }
  192. }
  193. // Last chance screening.
  194. require_once(BB2_CORE . "/screener.inc.php");
  195. bb2_screener($settings, $package);
  196. // And that's about it.
  197. bb2_approved($settings, $package);
  198. return false;
  199. }