configs->get_value('aiowps_enable_trash_spam_comments') && absint($aio_wp_security->configs->get_value('aiowps_trash_spam_comments_after_days'))) { $date_before = absint($aio_wp_security->configs->get_value('aiowps_trash_spam_comments_after_days')).' days ago'; $comment_ids = get_comments(array( 'fields' => 'ids', 'status' => 'spam', 'date_query' => array( array( 'before' => $date_before, 'inclusive' => true, ), ) )); if (!empty($comment_ids)) { foreach ($comment_ids as $comment_id) { wp_trash_comment($comment_id); } } } } /** * Delete ip from aiowps_permanent_block table once the comment's spam status changed. * * @param object $comment_data comment object. */ public function comment_spam_status_change($comment_data) { global $wpdb, $aio_wp_security; $comment_ip = $comment_data->comment_author_IP; // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- Direct query necessary. No caching required. $total_spam_comment = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->comments} WHERE comment_author_IP = %s AND comment_approved = 'spam'", $comment_ip) ); $min_comment_before_block = $aio_wp_security->configs->get_value('aiowps_spam_ip_min_comments_block'); if ($total_spam_comment < $min_comment_before_block) { $where = array('blocked_ip' => $comment_ip, 'block_reason' => 'spam'); // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- Direct query necessary. No caching required. $wpdb->delete(AIOWPSEC_TBL_PERM_BLOCK, $where, array('%s')); } } /** * Checks if comment posted by spambot. * * @return boolean. */ public static function is_comment_spam_detected() { $return = false; if (!is_user_logged_in()) { if (empty($_SERVER['HTTP_REFERER']) || false === stristr(sanitize_url(wp_unslash($_SERVER['HTTP_REFERER'])), wp_parse_url(home_url(), PHP_URL_HOST)) || empty($_SERVER['HTTP_USER_AGENT'])) { $return = true; } elseif (self::is_bot_detected()) { $return = true; } } return apply_filters('aiowps_is_comment_spam_detected', $return); } /** * Check if bot posted comment form based on form posted fields and cookie values * * @return boolean */ public static function is_bot_detected() { global $aio_wp_security; $return = false; $key_map_arr = self::generate_antibot_keys(); foreach ($key_map_arr[0] as $key) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- PCP warning. Nonce checked in earlier function. if (empty($_POST[$key[0]]) || sanitize_text_field(wp_unslash($_POST[$key[0]])) != $key[1]) { $return = true; break; } } if (!$return && '1' == $aio_wp_security->configs->get_value('aiowps_spambot_detect_usecookies')) { foreach ($key_map_arr[1] as $key) { if (AIOWPSecurity_Utility::get_cookie_value($key[0]) != $key[1]) { $return = true; break; } } } return apply_filters('aios_is_bot_detected', $return); } /** * Set cookies in browser for antibot check * * @return void */ public static function insert_antibot_keys_in_cookie() { $key_map_arr = self::generate_antibot_keys(); $expiry_seconds = AIOS_UPDATE_ANTIBOT_KEYS_AFTER_DAYS * 86400; if (!empty($key_map_arr[1])) { foreach ($key_map_arr[1] as $key) { AIOWPSecurity_Utility::set_cookie_value($key[0], $key[1], $expiry_seconds); } } } /** * Comment Form to post back hidden fields for antibot check * * @return string */ public static function insert_antibot_keys_in_comment_form() { $html_antibot_hidden_fields = '
%1$s
'; $antibot_hidden_fields = ''; $key_map_arr = self::generate_antibot_keys(); foreach ($key_map_arr[0] as $key) { $antibot_hidden_fields .=''; } if (isset($key_map_arr[2])) { $antibot_hidden_fields .=''; } wp_register_script('aios-front-js', AIO_WP_SECURITY_URL. '/js/wp-security-front-script.js', array('jquery'), AIO_WP_SECURITY_VERSION, true); wp_enqueue_script('aios-front-js'); wp_localize_script('aios-front-js', 'AIOS_FRONT', array( 'ajaxurl' => admin_url('admin-ajax.php'), // URL to wp-admin/admin-ajax.php to process the request 'ajax_nonce' => wp_create_nonce('wp-security-ajax-nonce'), )); $html_antibot_hidden_fields = sprintf($html_antibot_hidden_fields, $antibot_hidden_fields); return $html_antibot_hidden_fields; } /** * Get antibot key-value pairs to check on post back * * @param boolean $update generate and save in database * * @return array */ public static function generate_antibot_keys($update = false) { $key_map_arr = get_site_option('aios_antibot_key_map_info'); if (!$update && is_array($key_map_arr)) { return $key_map_arr; } if ($update && is_array($key_map_arr) && isset($key_map_arr[2]) && $key_map_arr[2] > time()) { return $key_map_arr; } $key_map_arr = array(); // values for to check post back key $max = wp_rand(2, 4); for ($i = 1; $i <= $max; $i++) { $string1 = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(8); $string2 = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(12); $key_map_arr[0][] = array($string1, $string2); } // values for to check for cookie back key $max = wp_rand(2, 4); for ($i = 1; $i <= $max; $i++) { $string1 = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(8); $string2 = AIOWPSecurity_Utility::generate_alpha_numeric_random_string(12); $key_map_arr[1][] = array($string1, $string2); } // expiration time of keys $current_time = time(); $key_map_arr[2] = (($current_time - ($current_time % 86400)) + AIOS_UPDATE_ANTIBOT_KEYS_AFTER_DAYS * 86400); update_site_option('aios_antibot_key_map_info', $key_map_arr); return $key_map_arr; } /** * Update antibot key-value pairs to rotate values so it is not valid forever * * @return void */ public function update_antibot_keys() { if ((intval(gmdate('z')) % AIOS_UPDATE_ANTIBOT_KEYS_AFTER_DAYS) == 0) self::generate_antibot_keys(true); } }