define('wpadtiddos_seconds_limit_GET',1); define('wpadtiddos_seconds_limit_XHR',3); class wp_antiddos { var $enable = true; var $hits_limit_GET = 3; // hits limit for GET requests (per wpadtiddos_seconds_limit_GET second) var $hits_limit_XHR = 3; // hits limit for XHR requests (per wpadtiddos_seconds_limit_XHR second) var $seconds_limit_POST = 3; // seconds limit for POST requests var $seconds_limit_AUTH = 3; // seconds limit for AUTH (Password) requests var $visitor; // status of visitor = raw|cool|warm|hot var $warm_level; // number of hits for last $seconds_limit seconds that cause visitor`s status turn to warm var $auto = true; // block visitors by AntiDDOS var $delay_time = 30; // seconds of delay of blocked visitors var $block_cnet = true; // block all C class net. var $cloudflare = true; // convert Cloudflare HTTP_CF_CONNECTING_IP to REMOTE_ADDR var $send_header = false; // send "WP_AntiDDOS: yes" header for debug purposes var $only_params_enabled = false; // Only Params feature enabled var $only_params = 's'; // the only GET/POST params that trigger checkup var $status, $error_msg; var $conn; // mysql connection var $hits = false; // actual hits number for current IP var $cookie = ''; // wpantiddos cookie value that prevents anti DDOS processing var $table_name = ''; var $pass_param = 'pwd'; // name of POST parameter that indentify Login (AUTH) request var $delay_message = 'Our server is currently overloaded, your request will be repeated automatically in %s seconds'; var $delay_message_auth = 'Our server is currently overloaded, your request will be repeated automatically in %s seconds'; public function __construct() { if (isset($GLOBALS['wp_antiddos_instance'])) return; else $GLOBALS['wp_antiddos_instance'] = &$this; if ($_SERVER['REMOTE_ADDR']=='127.0.0.1') return; $this->conn = mysqli_connect(DB_HOST,DB_USER,DB_PASSWORD); $ok = mysqli_select_db($this->conn,DB_NAME); if (!$ok) return false; $this->get_options(); // plugin disabled if (!$this->enable) return; // current request is admin's one if (isset($_COOKIE['wpantiddos']) && $_COOKIE['wpantiddos']==$this->cookie) return; if ($this->only_params_enabled) if (!$this->only_param_detected()) return; // detect request type and limits if ($this->xhr_request()) { if ($this->hits_limit_XHR=='ANY') return; $request_type = 'xhr'; $hits_limit = $this->hits_limit_XHR; $seconds_limit = wpadtiddos_seconds_limit_XHR; } elseif ($_POST && isset($_POST[$this->pass_param]) ) { if ($this->seconds_limit_AUTH=='ANY') return; $request_type = 'auth'; $seconds_limit = $this->seconds_limit_AUTH; $this->only_params .= ' '.$this->pass_param; $hits_limit = 1; } elseif ($_POST) { if ($this->seconds_limit_POST=='ANY') return; $request_type = 'post'; $hits_limit = 1; $seconds_limit = $this->seconds_limit_POST; } else { if ($this->hits_limit_GET=='ANY') return; $request_type = 'get'; $hits_limit = $this->hits_limit_GET; $seconds_limit = wpadtiddos_seconds_limit_GET; } if ($this->send_header) header("WP_AntiDDOS: yes"); if ($this->cloudflare) { if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP']; } $this->ip = $_SERVER['REMOTE_ADDR']; if ($this->block_cnet) $this->ip = substr($this->ip,0,strrpos($this->ip,'.')+1); $this->warm_level = ceil($hits_limit/2); try { $res = mysqli_query($this->conn,"SELECT count(*) kount FROM $this->table_name WHERE ip='".addslashes($this->ip)."' AND tstamp>".(time()-$seconds_limit)." AND type='$request_type'"); $row = mysqli_fetch_assoc($res); if (!$row) $this->error_msg = 'Error detected'; $this->hits = @$row['kount']+1; // consider current request too if ($this->hits==0) // if no hits from this IP $this->visitor = "new"; elseif ($this->hits>$hits_limit) $this->visitor = "hot"; elseif ($this->hits>=$this->warm_level) $this->visitor = "warm"; else $this->visitor = "cool"; // add current hit mysqli_query($this->conn,"INSERT INTO $this->table_name SET ip='$this->ip', type='$request_type', tstamp=".time()); // cleanup ip list $clear_time = max($this->delay_time,$seconds_limit); mysqli_query($this->conn,"DELETE FROM $this->table_name WHERE tstamp<".(time()-$clear_time)); } catch(Exception $e) { $this->error_msg = $e->getString(); $this->status = 'error'; mysqli_close($this->conn); return; } mysqli_close($this->conn); if (!empty($this->error_msg) ) { $this->status = 'error'; } if ($this->auto && $this->visitor=='hot') { header('HTTP/1.0 503 Service Unavailable'); header('Status: 503 Service Unavailable'); header("Retry-After: ".($this->delay_time+1)); // submit form first if POST request if (!$_POST) print "
"; else { $inputs = $this->array_to_fields($_POST); print ' '; } if ($request_type=='auth') printf("