Initial commit: Atomaste website

This commit is contained in:
2025-12-10 12:17:30 -05:00
commit 0b9e5d1605
19260 changed files with 5206382 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
<?php
namespace RSSSL\Security\Includes\Check404;
class Rsssl_Simple_404_Interceptor {
private $attempts = 10; // Default attempts threshold
private $time_span = 5; // Time span in seconds (5 seconds)
private $option_name = 'rsssl_404_cache';
private $notice_option = 'rsssl_404_notice_shown';
public function __construct() {
// Load the 404 test class only if the firewall has been enabled
if ( rsssl_get_option('enable_firewall') == '1' ) {
add_action( 'admin_init', array( $this, 'maybe_load_class_404_test' ), 20, 4 );
}
add_filter( 'rsssl_notices', array( $this, 'show_help_notices' ) );
if ( defined( 'rsssl_pro' ) ) {
return;
}
add_action( 'template_redirect', array( $this, 'detect_404' ) );
}
/**
* Detect and handle 404 errors.
*/
public function detect_404(): void {
if (is_404()) {
if ( get_option( $this->notice_option ) ) {
return;
}
$ip_address = $this->get_ip_address();
$current_time = time();
// Prevent the option from becoming too large
$cache = get_option($this->option_name, []);
if (!isset($cache[$ip_address])) {
$cache[$ip_address] = [];
}
$cache[$ip_address][] = $current_time;
$cache[$ip_address] = $this->clean_up_old_entries($cache[$ip_address]);
if (count($cache[$ip_address]) > $this->attempts && !get_option($this->notice_option)) {
update_option($this->notice_option, true, false);
return;
}
update_option($this->option_name, $cache, false);
}
}
/**
* Cleans up old entries based on the given timestamps.
*
* This method filters the given timestamps array and only keeps the entries where the difference between the current time
* and the timestamp is less than the specified time span.
*
* @param array $timestamps An array of timestamps.
*
* @return array The cleaned up timestamps array.
*/
private function clean_up_old_entries($timestamps): array {
$current_time = time();
return array_filter($timestamps, function($timestamp) use ($current_time) {
return ($current_time - $timestamp) < $this->time_span;
});
}
/**
* Retrieves the IP address of the client.
*
* This method checks for the IP address in the following order:
* 1. HTTP_CLIENT_IP: Represents the IP address of the client if the client is a shared internet device.
* 2. HTTP_X_FORWARDED_FOR: Represents the IP address of the client if the client is accessing the server through a proxy server.
* 3. REMOTE_ADDR: Represents the IP address of the client if the client is accessing the server directly.
*
* @return string The IP address of the client.
*/
private function get_ip_address(): string {
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
return $_SERVER['HTTP_CLIENT_IP'];
}
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
return $_SERVER['HTTP_X_FORWARDED_FOR'];
}
if (!empty($_SERVER['REMOTE_ADDR'])) {
return $_SERVER['REMOTE_ADDR'];
}
return 'UNKNOWN';
}
/**
* Add a help notice for 404 detection warning.
*
* @param array $notices The existing notices array.
*
* @return array Updated notices array with 404 detection warning notice.
*/
public function show_help_notices(array $notices): array {
if (get_option($this->notice_option)) {
$message = __('We detected suspected bots triggering large numbers of 404 errors on your site.', 'really-simple-ssl');
$notice = [
'callback' => '_true_',
'score' => 1,
'show_with_options' => ['enable_404_detection'],
'output' => [
'true' => [
'msg' => $message,
'icon' => 'warning',
'type' => 'warning',
'dismissible' => true,
'admin_notice' => false,
'highlight_field_id' => 'enable_firewall',
'plusone' => true,
'url' => 'https://really-simple-ssl.com/suspected-bots-causing-404-errors/',
]
]
];
$notices['404_detection_warning'] = $notice;
}
return $notices;
}
/**
* @param $field
* @param $value
* @param $old_value
* @param $option_name
*
* @return void
*/
public function maybe_load_class_404_test() {
if ( ! get_option( 'rsssl_homepage_contains_404_resources' ) ) {
Rsssl_Test_404::get_instance();
}
}
}
new Rsssl_Simple_404_Interceptor();

View File

@@ -0,0 +1,152 @@
<?php
namespace RSSSL\Security\Includes\Check404;
class Rsssl_Test_404 {
// Static instance property
public static $instance = null;
// Private constructor to prevent direct instantiation
private function __construct() {
// Immediately check if there are resources to process and handle them
$resources = get_option( 'rsssl_404_resources_to_check' );
$found_404_option_value = get_option( 'rsssl_homepage_contains_404_resources', false );
$found_404s = $found_404_option_value === true || $found_404_option_value === "true";
if ( ! empty( $resources ) && ! $found_404s ) {
// Trigger chunk processing if resources are pending
$this->process_404_resources_chunk();
}
$this->fetch_and_check_homepage_resources();
}
// Static method to get the single instance of the class
public static function get_instance() {
if ( self::$instance === null ) {
self::$instance = new self();
}
return self::$instance;
}
// Process resources in chunks
public function process_404_resources_chunk() {
$resources = get_option( 'rsssl_404_resources_to_check' );
if ( empty( $resources ) ) {
update_option( 'rsssl_homepage_contains_404_resources', 'false' );
return false;
}
// Process a chunk of the resources (e.g., 2 at a time)
$chunk_size = 2;
$resources_chunk = array_splice( $resources, 0, $chunk_size );
$result = $this->process_404_resources( $resources_chunk );
// Update the remaining resources back to the option
if ( ! empty( $resources ) ) {
update_option( 'rsssl_404_resources_to_check', $resources );
return 'processing';
} else {
// All resources have been processed
return $result;
}
}
// Function to check homepage and handle 404s
public static function homepage_contains_404_resources() {
$found_404_option_value = get_option( 'rsssl_homepage_contains_404_resources', false );
if ( $found_404_option_value === true || $found_404_option_value === "true" ) {
return true;
}
$resources = get_option( 'rsssl_404_resources_to_check' );
if ( ! empty( $resources ) ) {
// If resources are available to check, process them immediately
return self::get_instance()->process_404_resources_chunk();
}
}
// Function to fetch homepage resources and check for 404 errors
public function fetch_and_check_homepage_resources() {
if ( get_option('rsssl_homepage_contains_404_resources') ) {
return;
}
$site_url = trailingslashit( site_url() );
$response = wp_remote_get( $site_url );
if ( is_wp_error( $response ) ) {
update_option( 'rsssl_homepage_contains_404_resources', false );
return false;
}
$status_code = wp_remote_retrieve_response_code( $response );
if ( $status_code == 404 ) {
update_option( 'rsssl_homepage_contains_404_resources', true );
return true;
}
// Patterns to match img, script, link tags
$body = wp_remote_retrieve_body( $response );
$patterns = array(
'/<img[^>]+src=([\'"])?((.*?)\1)/i',
'/<script[^>]+src=([\'"])?((.*?)\1)/i',
'/<link[^>]+href=([\'"])?((.*?)\1)/i'
);
$resources = array();
foreach ( $patterns as $pattern ) {
if ( preg_match_all( $pattern, $body, $matches ) ) {
foreach ( $matches[2] as $resource_url ) {
$resource_url = esc_url_raw( $resource_url );
if ( strpos( $resource_url, $site_url ) !== false ) {
$resources[] = $resource_url;
}
}
}
}
if ( count( $resources ) > 2 ) {
update_option( 'rsssl_404_resources_to_check', $resources );
return $this->process_404_resources_chunk();
} else {
if ( empty( $resources ) ) {
update_option( 'rsssl_homepage_contains_404_resources', 'false' );
return false;
}
update_option( 'rsssl_404_resources_to_check', $resources );
// Process all resources if fewer than 5
return $this->process_404_resources( $resources );
}
}
// Function to process a list of resources and check for 404 errors
private function process_404_resources( $resources ) {
$not_found_resources = array();
foreach ( $resources as $resource_url ) {
$resource_response = wp_remote_head( $resource_url );
if ( is_wp_error( $resource_response ) ) {
$not_found_resources[] = $resource_url . ' (Error: ' . $resource_response->get_error_message() . ')';
} else {
$resource_status = wp_remote_retrieve_response_code( $resource_response );
if ( $resource_status == 404 ) {
$not_found_resources[] = $resource_url;
}
}
}
if ( empty( $not_found_resources ) ) {
update_option( 'rsssl_homepage_contains_404_resources', 'false' );
return false;
} else {
update_option( 'rsssl_homepage_contains_404_resources', 'true' );
return true;
}
}
}