/**
  * Determines whether a given IP address is whitelisted
  *
  * @param  string  $ip_to_check ip to check
  * @param  array   $white_ips   ip list to compare to if not yet saved to options
  * @param  boolean $current     whether to whitelist the current ip or not (due to saving, etc)
  *
  * @return boolean               true if whitelisted or false
  */
 public static function is_ip_whitelisted($ip_to_check, $white_ips = null, $current = false)
 {
     $ip_to_check = trim($ip_to_check);
     if ($white_ips === null) {
         $global_settings = get_site_option('itsec_global');
         $white_ips = isset($global_settings['lockout_white_list']) ? $global_settings['lockout_white_list'] : array();
     }
     if ($current === true) {
         $white_ips[] = ITSEC_Lib::get_ip();
         //add current user ip to whitelist to check automatically
     }
     foreach ($white_ips as $white_ip) {
         $converted_white_ip = ITSEC_Lib::ip_wild_to_mask($white_ip);
         $check_range = ITSEC_Lib::cidr_to_range($converted_white_ip);
         $ip_range = ITSEC_Lib::cidr_to_range($ip_to_check);
         if (sizeof($check_range) === 2) {
             //range to check
             $check_min = ip2long($check_range[0]);
             $check_max = ip2long($check_range[1]);
             if (sizeof($ip_range) === 2) {
                 $ip_min = ip2long($ip_range[0]);
                 $ip_max = ip2long($ip_range[1]);
                 /**
                  * Checks cover the following scenarios:
                  *  - min-a, min-b, max-a, max-b : min-b is in a range and min-a is in b range
                  *  - min-b, min-a, max-b, max-a : max-b is in a range and max-a is in b range
                  *  - min-a, min-b, max-b, max-a : range b is encapsulated by range a
                  *  - min-b, min-a, max-a, max-b : range a is encapsulated by range b
                  */
                 if ($check_min <= $ip_min && $ip_min <= $check_max || $check_min <= $ip_max && $ip_max <= $check_max || $ip_min <= $check_min && $check_min <= $ip_max || $ip_min <= $check_max && $check_max <= $ip_max) {
                     return true;
                 }
             } else {
                 $ip = ip2long($ip_range[0]);
                 if ($check_min <= $ip && $ip <= $check_max) {
                     return true;
                 }
             }
         } else {
             //single ip to check
             $check = ip2long($check_range[0]);
             if (sizeof($ip_range) === 2) {
                 $ip_min = ip2long($ip_range[0]);
                 $ip_max = ip2long($ip_range[1]);
                 if ($ip_min <= $check && $check <= $ip_max) {
                     return true;
                 }
             } else {
                 $ip = ip2long($ip_range[0]);
                 if ($check == $ip) {
                     return true;
                 }
             }
         }
     }
     return false;
 }
Exemplo n.º 2
0
 /**
  * Determines whether a given IP address is whitelisted
  *
  * @param  string  $ip_to_check ip to check
  * @param  array   $white_ips   ip list to compare to if not yet saved to options
  * @param  boolean $current     whether to whitelist the current ip or not (due to saving, etc)
  *
  * @return boolean               true if whitelisted or false
  */
 public static function is_ip_whitelisted($ip_to_check, $white_ips = null, $current = false)
 {
     $ip_to_check = trim($ip_to_check);
     if ($white_ips === null) {
         $global_settings = get_site_option('itsec_global');
         $white_ips = isset($global_settings['lockout_white_list']) ? $global_settings['lockout_white_list'] : array();
     }
     if ($current === true) {
         $white_ips[] = ITSEC_Lib::get_ip();
         //add current user ip to whitelist to check automatically
     }
     foreach ($white_ips as $white_ip) {
         $converted_white_ip = ITSEC_Lib::ip_wild_to_mask($white_ip);
         $check_range = ITSEC_Lib::cidr_to_range($converted_white_ip);
         $ip_range = ITSEC_Lib::cidr_to_range($ip_to_check);
         if (sizeof($check_range) === 2) {
             //range to check
             $check_min = ip2long($check_range[0]);
             $check_max = ip2long($check_range[1]);
             if (sizeof($ip_range) === 2) {
                 $ip_min = ip2long($ip_range[0]);
                 $ip_max = ip2long($ip_range[1]);
                 if ($check_min < $ip_min && $ip_min < $check_max || $check_min < $ip_max && $ip_max < $check_max) {
                     return true;
                 }
             } else {
                 $ip = ip2long($ip_range[0]);
                 if ($check_min < $ip && $ip < $check_max) {
                     return true;
                 }
             }
         } else {
             //single ip to check
             $check = ip2long($check_range[0]);
             if (sizeof($ip_range) === 2) {
                 $ip_min = ip2long($ip_range[0]);
                 $ip_max = ip2long($ip_range[1]);
                 if ($ip_min < $check && $check < $ip_max) {
                     return true;
                 }
             } else {
                 $ip = ip2long($ip_range[0]);
                 if ($check == $ip) {
                     return true;
                 }
             }
         }
     }
     return false;
 }
Exemplo n.º 3
0
 /**
  * Determines whether a given IP address is whitelisted.
  *
  * @since  4.0
  *
  * @access private
  *
  * @param  string $ip_to_check ip to check
  *
  * @return boolean               true if whitelisted or false
  */
 private function is_ip_whitelisted($ip_to_check, $current = false)
 {
     global $itsec_globals;
     $white_ips = $itsec_globals['settings']['lockout_white_list'];
     if (!is_array($white_ips)) {
         $white_ips = explode(PHP_EOL, $white_ips);
     }
     //Add the server IP address
     if (isset($_SERVER['LOCAL_ADDR'])) {
         $white_ips[] = $_SERVER['LOCAL_ADDR'];
     } elseif (isset($_SERVER['SERVER_ADDR'])) {
         $white_ips[] = $_SERVER['SERVER_ADDR'];
     }
     if ($current === true) {
         $white_ips[] = ITSEC_Lib::get_ip();
         //add current user ip to whitelist to check automatically
     }
     $temp = get_site_option('itsec_temp_whitelist_ip');
     if ($temp !== false) {
         if ($temp['exp'] < $itsec_globals['current_time']) {
             delete_site_option('itsec_temp_whitelist_ip');
         } else {
             $white_ips[] = filter_var($temp['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
         }
     }
     if (is_array($white_ips) && sizeof($white_ips > 0)) {
         foreach ($white_ips as $white_ip) {
             $converted_white_ip = ITSEC_Lib::ip_wild_to_mask($white_ip);
             $check_range = ITSEC_Lib::cidr_to_range($converted_white_ip);
             $ip_range = ITSEC_Lib::cidr_to_range($ip_to_check);
             if (sizeof($check_range) === 2) {
                 //range to check
                 $check_min = ip2long($check_range[0]);
                 $check_max = ip2long($check_range[1]);
                 if (sizeof($ip_range) === 2) {
                     $ip_min = ip2long($ip_range[0]);
                     $ip_max = ip2long($ip_range[1]);
                     if ($check_min < $ip_min && $ip_min < $check_max || $check_min < $ip_max && $ip_max < $check_max) {
                         return true;
                     }
                 } else {
                     $ip = ip2long($ip_range[0]);
                     if ($check_min < $ip && $ip < $check_max) {
                         return true;
                     }
                 }
             } else {
                 //single ip to check
                 $check = ip2long($check_range[0]);
                 if (sizeof($ip_range) === 2) {
                     $ip_min = ip2long($ip_range[0]);
                     $ip_max = ip2long($ip_range[1]);
                     if ($ip_min < $check && $check < $ip_max) {
                         return true;
                     }
                 } else {
                     $ip = ip2long($ip_range[0]);
                     if ($check == $ip) {
                         return true;
                     }
                 }
             }
         }
     }
     return false;
 }
 protected function get_server_config_ban_hosts_rules($server_type)
 {
     if (true !== $this->settings['enabled']) {
         return '';
     }
     if (!is_array($this->settings['host_list']) || empty($this->settings['host_list'])) {
         return '';
     }
     if (!class_exists('ITSEC_Ban_Users')) {
         require dirname(__FILE__) . '/class-itsec-ban-users.php';
     }
     $host_rules = '';
     $set_env_rules = '';
     $deny_rules = '';
     $require_rules = '';
     // process hosts list
     foreach ($this->settings['host_list'] as $host) {
         $host = ITSEC_Lib::ip_wild_to_mask($host);
         $host = trim($host);
         if (empty($host)) {
             continue;
         }
         if (ITSEC_Ban_Users::is_ip_whitelisted($host)) {
             /**
              * @todo warn the user the ip to be banned is whitelisted
              */
             continue;
         }
         if (in_array($server_type, array('apache', 'litespeed'))) {
             $converted_host = ITSEC_Lib::ip_mask_to_range($host);
             $converted_host = trim($converted_host);
             if (empty($converted_host)) {
                 continue;
             }
             $set_env_host = str_replace('.', '\\.', $converted_host);
             $set_env_rules .= "\tSetEnvIF REMOTE_ADDR \"^{$set_env_host}\$\" DenyAccess\n";
             // Ban IP
             $set_env_rules .= "\tSetEnvIF X-FORWARDED-FOR \"^{$set_env_host}\$\" DenyAccess\n";
             // Ban IP from a proxy
             $set_env_rules .= "\tSetEnvIF X-CLUSTER-CLIENT-IP \"^{$set_env_host}\$\" DenyAccess\n";
             // Ban IP from a load balancer
             $set_env_rules .= "\n";
             $require_host = str_replace('.[0-9]+', '', $converted_host);
             $require_rules .= "\t\t\tRequire not ip {$require_host}\n";
             $deny_rules .= "\t\tDeny from {$require_host}\n";
         } else {
             if ('nginx' === $server_type) {
                 $host_rules .= "\tdeny {$host};\n";
             }
         }
     }
     $rules = '';
     if ('apache' === $server_type) {
         if (!empty($set_env_rules)) {
             $rules .= "\n";
             $rules .= "\t# " . __('Ban Hosts - Security > Settings > Banned Users', 'better-wp-security') . "\n";
             $rules .= $set_env_rules;
             $rules .= "\t<IfModule mod_authz_core.c>\n";
             $rules .= "\t\t<RequireAll>\n";
             $rules .= "\t\t\tRequire all granted\n";
             $rules .= "\t\t\tRequire not env DenyAccess\n";
             $rules .= $require_rules;
             $rules .= "\t\t</RequireAll>\n";
             $rules .= "\t</IfModule>\n";
             $rules .= "\t<IfModule !mod_authz_core.c>\n";
             $rules .= "\t\tOrder allow,deny\n";
             $rules .= "\t\tAllow from all\n";
             $rules .= "\t\tDeny from env=DenyAccess\n";
             $rules .= $deny_rules;
             $rules .= "\t</IfModule>\n";
         }
     } else {
         if ('litespeed' === $server_type) {
             if (!empty($set_env_rules)) {
                 $rules .= "\n";
                 $rules .= "\t# " . __('Ban Hosts - Security > Settings > Banned Users', 'better-wp-security') . "\n";
                 $rules .= $set_env_rules;
                 $rules .= "\t<IfModule mod_litespeed.c>\n";
                 $rules .= "\t\tOrder allow,deny\n";
                 $rules .= "\t\tAllow from all\n";
                 $rules .= "\t\tDeny from env=DenyAccess\n";
                 $rules .= $deny_rules;
                 $rules .= "\t</IfModule>\n";
             }
         } else {
             if ('nginx' === $server_type) {
                 if (!empty($host_rules)) {
                     $rules .= "\n";
                     $rules .= "# " . __('Ban Hosts - Security > Settings > Banned Users', 'better-wp-security') . "\n";
                     $rules .= $host_rules;
                 }
             }
         }
     }
     return $rules;
 }
 /**
  * Build the rewrite rules and sends them to the file writer
  *
  * @param array   $input   array of options, ips, etc
  * @param boolean $current whether the current IP can be included in the ban list
  *
  * @return array array of rules to send to file writer
  */
 public static function build_rewrite_rules($input = null, $current = false)
 {
     //setup data structures to write. These are simply lists of all IPs and hosts as well as options to check
     if ($input === null) {
         //blocking ip on the fly
         $input = get_site_option('itsec_ban_users');
     }
     $default = $input['default'];
     $enabled = $input['enabled'];
     $raw_host_list = $input['host_list'];
     $raw_agent_list = $input['agent_list'];
     $server_type = ITSEC_Lib::get_server();
     //Get the server type to build the right rules
     //initialize lists so we can check later if we've used them
     $host_list = '';
     $agent_list = '';
     $default_list = '';
     $host_rule2 = '';
     //load the default blacklist if needed
     if ($default === true && $server_type === 'nginx') {
         $default_list = file_get_contents(plugin_dir_path(__FILE__) . 'lists/hackrepair-nginx.inc');
     } elseif ($default === true) {
         $default_list = file_get_contents(plugin_dir_path(__FILE__) . 'lists/hackrepair-apache.inc');
     }
     //Only process other lists if the feature has been enabled
     if ($enabled === true) {
         //process hosts list
         if (is_array($raw_host_list)) {
             foreach ($raw_host_list as $host) {
                 $host = ITSEC_Lib::ip_wild_to_mask($host);
                 if (!class_exists('ITSEC_Ban_Users')) {
                     require dirname(__FILE__) . '/class-itsec-ban-users.php';
                 }
                 if (!ITSEC_Ban_Users::is_ip_whitelisted($host, null, $current)) {
                     $converted_host = ITSEC_Lib::ip_mask_to_range($host);
                     if (strlen(trim($converted_host)) > 1) {
                         if ($server_type === 'nginx') {
                             //NGINX rules
                             $host_rule = "\tdeny " . trim($host) . ';';
                         } else {
                             //rules for all other servers
                             $dhost = str_replace('.', '\\.', trim($converted_host));
                             //re-define $dhost to match required output for SetEnvIf-RegEX
                             $host_rule = "SetEnvIF REMOTE_ADDR \"^" . $dhost . "\$\" DenyAccess" . PHP_EOL;
                             //Ban IP
                             $host_rule .= "SetEnvIF X-FORWARDED-FOR \"^" . $dhost . "\$\" DenyAccess" . PHP_EOL;
                             //Ban IP from Proxy-User
                             $host_rule .= "SetEnvIF X-CLUSTER-CLIENT-IP \"^" . $dhost . "\$\" DenyAccess" . PHP_EOL;
                             //Ban IP for Cluster/Cloud-hosted WP-Installs
                             $host_rule2 .= "deny from " . str_replace('.[0-9]+', '', trim($converted_host)) . PHP_EOL;
                         }
                     }
                     $host_list .= $host_rule . PHP_EOL;
                     //build large string of all hosts
                 } else {
                     /**
                      * @todo warn the user the ip to be banned is whitelisted
                      */
                 }
             }
         }
         //Process the agents list
         if (is_array($raw_agent_list)) {
             $count = 1;
             //to help us find the last one
             foreach ($raw_agent_list as $agent) {
                 if (strlen(trim($agent)) > 1) {
                     //if it isn't the last rule make sure we add an or
                     if ($count < sizeof($agent)) {
                         $end = ' [NC,OR]' . PHP_EOL;
                     } else {
                         $end = ' [NC]' . PHP_EOL;
                     }
                     if (strlen(trim($agent)) > 1) {
                         if ($server_type === 'nginx') {
                             //NGINX rule
                             $converted_agent = 'if ($http_user_agent ~* "^' . quotemeta(trim($agent)) . '"){ return 403; }' . PHP_EOL;
                         } else {
                             //Rule for all other servers
                             $converted_agent = 'RewriteCond %{HTTP_USER_AGENT} ^' . str_replace(' ', '\\ ', quotemeta(trim($agent))) . $end;
                         }
                     }
                     $agent_list .= $converted_agent;
                     //build large string of all agents
                 }
                 $count++;
             }
         }
     }
     $rules = '';
     //initialize rules
     //Start with default rules if we have them
     if (strlen($default_list) > 1) {
         $rules .= $default_list;
     }
     //Add banned host lists
     if (strlen($host_list) > 1 || strlen($default_list)) {
         if (strlen($default_list) > 1) {
             $rules .= PHP_EOL;
         }
         if ($server_type === 'nginx' && strlen($host_list) > 1) {
             //NGINX rules
             $rules .= $host_list;
         } elseif (strlen($host_list) > 1) {
             $rules .= $host_list . 'order allow,deny' . PHP_EOL . 'deny from env=DenyAccess' . PHP_EOL . $host_rule2 . 'allow from all' . PHP_EOL;
         }
     }
     //Add banned user agents
     if (strlen($agent_list) > 1) {
         if (strlen($default_list) > 1 || strlen($host_list) > 1) {
             $rules .= PHP_EOL;
         }
         if ($server_type === 'nginx') {
             //NGINX rules
             $rules .= $agent_list;
         } else {
             $rules .= '<IfModule mod_rewrite.c>' . PHP_EOL;
             $rules .= 'RewriteEngine On' . PHP_EOL;
             $rules .= $agent_list;
             $rules .= 'RewriteRule ^(.*)$ - [F]' . PHP_EOL;
             $rules .= '</IfModule>' . PHP_EOL;
         }
     }
     if (strlen($rules) > 0) {
         $rules = explode(PHP_EOL, $rules);
     } else {
         $rules = false;
     }
     //create a proper array for writing
     return array('type' => 'htaccess', 'priority' => 1, 'name' => 'Ban Users', 'rules' => $rules);
 }