class AntiCrawler in Anti Spam by CleanTalk 8.4
Same name and namespace in other branches
- 9.1.x src/lib/Cleantalk/Common/Firewall/Modules/AntiCrawler.php \Cleantalk\Common\Firewall\Modules\AntiCrawler
Hierarchy
- class \Cleantalk\Common\Firewall\FirewallModule
- class \Cleantalk\Common\Firewall\Modules\AntiCrawler
Expanded class hierarchy of AntiCrawler
1 file declares its use of AntiCrawler
- BootSubscriber.php in src/
EventSubscriber/ BootSubscriber.php
File
- src/
lib/ Cleantalk/ Common/ Firewall/ Modules/ AntiCrawler.php, line 11
Namespace
Cleantalk\Common\Firewall\ModulesView source
class AntiCrawler extends FirewallModule {
/**
* Public module name
*
* @var string
*/
public $module_name = 'ANTICRAWLER';
/**
* Signature - User-Agent + Protocol
*
* @var string
*/
private $sign;
private $store_interval = 60;
/**
* @var false|string
*/
private $antibot_cookie_value;
/**
* @var string
*/
private $ua_bl_table_name;
/**
* @var string|null
*/
private $db__table__ac_logs;
/**
* @var string|null
*/
private $db__table__sfw_logs;
private $db__table__sfw;
public function __construct($data_table = 'cleantalk_ac_logs', $params = []) {
$db = DB::getInstance();
$this->ua_bl_table_name = $db->prefix . $data_table;
$this->db__table__ac_logs = $params['db__table__ac_logs'] ? $db->prefix . $params['db__table__ac_logs'] : null;
$this->db__table__sfw_logs = $params['db__table__sfw_logs'] ? $db->prefix . $params['db__table__sfw_logs'] : null;
$this->db__table__sfw = $params['db__table__sfw'] ? $db->prefix . $params['db__table__sfw'] : null;
$this->sign = md5(Server::get('HTTP_USER_AGENT') . Server::get('HTTPS') . Server::get('HTTP_HOST'));
$this->antibot_cookie_value = CleantalkFuncs::create_ac_cookie_value();
}
/**
* Use this method to execute main logic of the module.
*
* @return array Array of the check results
*/
public function check() {
$results = array();
foreach ($this->ip_array as $current_ip) {
// Skip by 301 response code
if ($this
->is_redirected()) {
$results[] = array(
'ip' => $current_ip,
'is_personal' => false,
'status' => 'PASS_ANTICRAWLER',
);
return $results;
}
// UA check
$ua_bl_results = $this->db
->fetch_all("SELECT * FROM " . $this->ua_bl_table_name . " ORDER BY `ua_status` DESC;");
if (!empty($ua_bl_results)) {
$is_blocked = false;
foreach ($ua_bl_results as $ua_bl_result) {
if (!empty($ua_bl_result['ua_template']) && preg_match("%" . str_replace('"', '', $ua_bl_result['ua_template']) . "%i", Server::get('HTTP_USER_AGENT'))) {
if ($ua_bl_result['ua_status'] == 1) {
// Whitelisted
$results[] = array(
'ip' => $current_ip,
'is_personal' => false,
'status' => 'PASS_ANTICRAWLER_UA',
);
return $results;
}
else {
// Blacklisted
$results[] = array(
'ip' => $current_ip,
'is_personal' => false,
'status' => 'DENY_ANTICRAWLER_UA',
);
$is_blocked = true;
break;
}
}
}
if (!$is_blocked) {
$results[] = array(
'ip' => $current_ip,
'is_personal' => false,
'status' => 'PASS_ANTICRAWLER_UA',
);
}
}
// Skip by cookie
if (CleantalkFuncs::apbct_getcookie('apbct_antibot') == $this->antibot_cookie_value) {
if (CleantalkFuncs::apbct_getcookie('apbct_anticrawler_passed') == 1) {
if (!headers_sent()) {
CleantalkFuncs::apbct_setcookie('apbct_anticrawler_passed', '0');
}
}
$results[] = array(
'ip' => $current_ip,
'is_personal' => false,
'status' => 'PASS_ANTICRAWLER',
);
return $results;
}
}
// Common check
foreach ($this->ip_array as $current_ip) {
// IP check
$result = $this->db
->fetch("SELECT ip" . ' FROM `' . $this->db__table__ac_logs . '`' . " WHERE `ip` = '{$current_ip}'" . " AND `ua` = '{$this->sign}' AND " . rand(1, 100000) . ";");
if (isset($result['ip'])) {
if (CleantalkFuncs::apbct_getcookie('apbct_antibot') !== $this->antibot_cookie_value) {
$results[] = array(
'ip' => $current_ip,
'is_personal' => false,
'status' => 'DENY_ANTICRAWLER',
);
}
else {
if (CleantalkFuncs::apbct_getcookie('apbct_anticrawler_passed') === '1') {
if (!headers_sent()) {
CleantalkFuncs::apbct_setcookie('apbct_anticrawler_passed', '0');
}
// Do logging an one passed request
$this
->update_log($current_ip, 'PASS_ANTICRAWLER');
$results[] = array(
'ip' => $current_ip,
'is_personal' => false,
'status' => 'PASS_ANTICRAWLER',
);
return $results;
}
}
}
else {
if (!CleantalkFuncs::apbct_getcookie('apbct_antibot')) {
$this
->update_ac_log();
}
}
}
return $results;
}
public function actionsForDenied($result) {
// TODO: Implement actionsForDenied() method.
}
public function actionsForPassed($result) {
// TODO: Implement actionsForPassed() method.
}
private function is_redirected() {
$is_redirect = false;
if (Server::get('HTTP_REFERER') !== '' && Server::get('HTTP_HOST') !== '' && $this
->is_cloudflare()) {
$parse_referer = parse_url(Server::get('HTTP_REFERER'));
if ($parse_referer && isset($parse_referer['host'])) {
$is_redirect = Server::get('HTTP_HOST') !== $parse_referer['host'];
}
}
return http_response_code() === 301 || http_response_code() === 302 || $is_redirect;
}
private function is_cloudflare() {
return Server::get('HTTP_CF_RAY') && Server::get('HTTP_CF_CONNECTING_IP') && Server::get('HTTP_CF_REQUEST_ID');
}
/**
* Add entry to SFW log.
* Writes to database.
*
* @param string $ip
* @param string $status
* @param string $network
* @param string $source
*/
public function update_log($ip, $status, $network = null, $source = null) {
$id = md5($ip . $this->module_name);
$time = time();
if (!$source) {
$source = 'NULL';
}
if (!$network) {
$network = 'NULL';
}
$query = "INSERT INTO `{$this->db__table__sfw_logs}`\n\t\tSET\n\t\t\t`id` = '{$id}',\n\t\t\t`ip` = '{$ip}',\n\t\t\t`status` = '{$status}',\n\t\t\t`all_entries` = 1,\n\t\t\t`blocked_entries` = " . (strpos($status, 'DENY') !== false ? 1 : 0) . ",\n\t\t\t`entries_timestamp` = '{$time}',\n\t\t\t`ua_name` = '" . Server::get('HTTP_USER_AGENT') . "',\n\t\t\t`source` = {$source},\n\t\t\t`network` = '{$network}',\n `first_url` = '" . substr(Server::get('HTTP_HOST') . Server::get('REQUEST_URI'), 0, 100) . "',\n `last_url` = '" . substr(Server::get('HTTP_HOST') . Server::get('REQUEST_URI'), 0, 100) . "'\n\t\tON DUPLICATE KEY\n\t\tUPDATE\n\t\t\t`status` = '{$status}',\n\t\t\t`source` = {$source},\n\t\t\t`all_entries` = `all_entries` + 1,\n\t\t\t`blocked_entries` = `blocked_entries`" . (strpos($status, 'DENY') !== false ? ' + 1' : '') . ",\n\t\t\t`entries_timestamp` = '{$time}',\n\t\t\t`ua_name` = '" . Server::get('HTTP_USER_AGENT') . "',\n\t\t\t`network` = '{$network}',\n `last_url` = '" . substr(Server::get('HTTP_HOST') . Server::get('REQUEST_URI'), 0, 100) . "'";
$this->db
->execute(str_replace(';', '', $query));
}
/**
* Update ac logs table
*/
public function update_ac_log() {
$interval_time = Helper::time__get_interval_start($this->store_interval);
foreach ($this->ip_array as $current_ip) {
$id = md5($current_ip . $this->sign . $interval_time);
$this->db
->execute("INSERT INTO " . $this->db__table__ac_logs . " SET\n\t\t\t\t\tid = '{$id}',\n\t\t\t\t\tip = '{$current_ip}',\n\t\t\t\t\tua = '{$this->sign}',\n\t\t\t\t\tentries = 1,\n\t\t\t\t\tinterval_start = {$interval_time}\n\t\t\t\tON DUPLICATE KEY UPDATE\n\t\t\t\t\tip = ip,\n\t\t\t\t\tentries = entries + 1,\n\t\t\t\t\tinterval_start = {$interval_time};");
}
}
/**
* @inheritdoc
*/
public function _die($result) {
parent::_die($result);
// File exists?
if (file_exists(__DIR__ . "/die_page_anticrawler.html")) {
$die_page = file_get_contents(__DIR__ . "/die_page_anticrawler.html");
$net_count = $this->db
->fetch('SELECT COUNT(*) as net_count FROM ' . $this->db__table__sfw)['net_count'];
// Translation
$replaces = array(
'{SFW_DIE_NOTICE_IP}' => 'Anti-Crawler Protection is activated for your IP ',
'{SFW_DIE_MAKE_SURE_JS_ENABLED}' => 'To continue working with the web site, please make sure that you have enabled JavaScript.',
'{SFW_DIE_YOU_WILL_BE_REDIRECTED}' => 'You will be automatically redirected to the requested page after 3 seconds.<br>' . 'Don\'t close this page. Please, wait for 3 seconds to pass to the page.',
'{CLEANTALK_TITLE}' => $this
->__('Antispam by CleanTalk', 'cleantalk-spam-protect'),
'{REMOTE_ADDRESS}' => $result['ip'],
'{SERVICE_ID}' => $net_count,
'{HOST}' => '',
'{COOKIE_ANTICRAWLER}' => $this->antibot_cookie_value,
'{COOKIE_ANTICRAWLER_PASSED}' => '1',
'{GENERATED}' => '<p>The page was generated at ' . date('D, d M Y H:i:s') . "</p>",
'{USE_ALT_COOKIES}' => \Drupal::config('cleantalk.settings')
->get('cleantalk_alternative_cookies_session') ? 1 : 0,
);
foreach ($replaces as $place_holder => $replace) {
$die_page = str_replace($place_holder, $replace, $die_page);
}
if (isset($_GET['debug'])) {
$debug = '<h1>Headers</h1>' . str_replace("\n", "<br>", print_r(\apache_request_headers(), true)) . '<h1>$_SERVER</h1>' . str_replace("\n", "<br>", print_r($_SERVER, true)) . '<h1>IPS</h1>' . str_replace("\n", "<br>", print_r($this->ip_array, true));
}
else {
$debug = '';
}
$die_page = str_replace("{DEBUG}", $debug, $die_page);
die($die_page);
}
die("IP BLACKLISTED. Blocked by AntiCrawler " . $result['ip']);
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AntiCrawler:: |
private | property | ||
AntiCrawler:: |
private | property | ||
AntiCrawler:: |
private | property | ||
AntiCrawler:: |
private | property | ||
AntiCrawler:: |
public | property |
Public module name Overrides FirewallModule:: |
|
AntiCrawler:: |
private | property | Signature - User-Agent + Protocol | |
AntiCrawler:: |
private | property | ||
AntiCrawler:: |
private | property | ||
AntiCrawler:: |
public | function |
Do logic for denied request. Overrides FirewallModule:: |
|
AntiCrawler:: |
public | function |
Do logic for allowed request. Overrides FirewallModule:: |
|
AntiCrawler:: |
public | function |
Use this method to execute main logic of the module. Overrides FirewallModule:: |
|
AntiCrawler:: |
private | function | ||
AntiCrawler:: |
private | function | ||
AntiCrawler:: |
public | function | Update ac logs table | |
AntiCrawler:: |
public | function | Add entry to SFW log. Writes to database. | |
AntiCrawler:: |
public | function |
@inheritdoc Overrides FirewallModule:: |
|
AntiCrawler:: |
public | function |
* FirewallModule constructor.
* Use this method to prepare any data for the module working.
*
* Overrides FirewallModule:: |
|
FirewallModule:: |
protected | property | ||
FirewallModule:: |
protected | property | ||
FirewallModule:: |
protected | property | ||
FirewallModule:: |
protected | property | ||
FirewallModule:: |
protected | property | ||
FirewallModule:: |
protected | property | ||
FirewallModule:: |
protected | property | ||
FirewallModule:: |
protected | property | ||
FirewallModule:: |
protected | property | * | |
FirewallModule:: |
protected | property | * | |
FirewallModule:: |
protected | property | * | |
FirewallModule:: |
public | function | Configure and set additional properties: real_ip, test_ip, test | |
FirewallModule:: |
public | function | Set API KEY | |
FirewallModule:: |
public | function | Set specify CMS based DB instance | |
FirewallModule:: |
public | function | Set specify CMS based Helper instance | |
FirewallModule:: |
public | function | Set visitor's IP | |
FirewallModule:: |
public | function | Set is debug property. | |
FirewallModule:: |
public | function | Set Log Table name | |
FirewallModule:: |
public | function | This is a placeholder for WP translation function. For compatibility with any CMS. |