current_time('mysql'), 'timestamp_utc' => gmdate('Y-m-d H:i:s'), 'event_type' => $event_type, 'severity' => $severity, 'severity_name' => self::get_severity_name($severity), 'message' => $message, 'context' => $context, 'client_id' => $client_id, 'user_id' => $user_id, 'session_id' => self::get_session_id(), 'request_data' => self::get_sanitized_request_data(), 'client_info' => self::get_client_info(), 'wordpress_info' => self::get_wordpress_info(), ]; // Store in database for structured querying self::store_security_event($event_data); // Log to WordPress error log for immediate visibility self::log_to_wordpress($event_data); // Send real-time alerts for critical events if ($severity >= self::SEVERITY_HIGH) { self::send_security_alert($event_data); } // Trigger WordPress action for external integrations do_action('tigerstyle_scent_security_event', $event_data); // Check for attack patterns and auto-block threats self::analyze_attack_patterns($event_data); // Real-time threat analysis self::perform_threat_analysis($event_data); } /** * 🔐 SECURITY: Store security event in database */ private static function store_security_event(array $event_data): void { global $wpdb; $table_name = $wpdb->prefix . 'tigerstyle_scent_security_log'; // Create table if it doesn't exist self::ensure_security_log_table(); $wpdb->insert( $table_name, [ 'timestamp' => $event_data['timestamp'], 'event_type' => $event_data['event_type'], 'severity' => $event_data['severity'], 'message' => $event_data['message'], 'context_data' => json_encode($event_data['context']), 'client_id' => $event_data['client_id'], 'user_id' => $event_data['user_id'], 'session_id' => $event_data['session_id'], 'client_ip' => $event_data['client_info']['ip'], 'user_agent' => substr($event_data['client_info']['user_agent'], 0, 255), 'request_uri' => $event_data['request_data']['uri'], 'request_method' => $event_data['request_data']['method'], 'full_event_data' => json_encode($event_data) ], [ '%s', '%s', '%d', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%s', '%s', '%s' ] ); } /** * 🔐 SECURITY: Ensure security log table exists */ private static function ensure_security_log_table(): void { global $wpdb; $table_name = $wpdb->prefix . 'tigerstyle_scent_security_log'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE IF NOT EXISTS $table_name ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, timestamp datetime NOT NULL, event_type varchar(50) NOT NULL, severity tinyint(1) NOT NULL, message text NOT NULL, context_data longtext, client_id varchar(255), user_id bigint(20) unsigned, session_id varchar(64), client_ip varchar(45) NOT NULL, user_agent varchar(255), request_uri varchar(255), request_method varchar(10), full_event_data longtext, created_at timestamp DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY event_type (event_type), KEY severity (severity), KEY timestamp (timestamp), KEY client_id (client_id), KEY user_id (user_id), KEY client_ip (client_ip) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); } /** * 🔐 SECURITY: Log to WordPress error log */ private static function log_to_wordpress(array $event_data): void { if (defined('WP_DEBUG') && WP_DEBUG) { $log_message = sprintf( '[TigerStyle Scent Security] %s [%s] %s - IP: %s, UA: %s', $event_data['severity_name'], $event_data['event_type'], $event_data['message'], $event_data['client_info']['ip'], substr($event_data['client_info']['user_agent'], 0, 50) ); error_log($log_message); } } /** * 🔐 SECURITY: Send real-time security alerts */ private static function send_security_alert(array $event_data): void { // Email alerts for critical security events if ($event_data['severity'] >= self::SEVERITY_CRITICAL) { $admin_email = get_option('admin_email'); $site_name = get_bloginfo('name'); $subject = "[CRITICAL] Security Alert - {$site_name}"; $message = "Critical security event detected:\n\n"; $message .= "Event: {$event_data['event_type']}\n"; $message .= "Message: {$event_data['message']}\n"; $message .= "Time: {$event_data['timestamp']}\n"; $message .= "IP: {$event_data['client_info']['ip']}\n"; $message .= "User Agent: {$event_data['client_info']['user_agent']}\n\n"; $message .= "Please review your security logs immediately."; wp_mail($admin_email, $subject, $message); } // WordPress admin notices for high severity events if ($event_data['severity'] >= self::SEVERITY_HIGH) { set_transient('tigerstyle_scent_security_alert', $event_data, 3600); } } /** * 🔐 SECURITY: Analyze attack patterns */ private static function analyze_attack_patterns(array $event_data): void { global $wpdb; $table_name = $wpdb->prefix . 'tigerstyle_scent_security_log'; $client_ip = $event_data['client_info']['ip']; // Check for repeated attacks from same IP in last hour $recent_attacks = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $table_name WHERE client_ip = %s AND severity >= %d AND timestamp > DATE_SUB(NOW(), INTERVAL 1 HOUR)", $client_ip, self::SEVERITY_MEDIUM ) ); // Auto-block IPs with excessive attacks if ($recent_attacks >= 5) { self::log_security_event( self::EVENT_SECURITY_VIOLATION, self::SEVERITY_CRITICAL, "IP auto-blocked for repeated security violations: {$client_ip}", ['attack_count' => $recent_attacks, 'auto_blocked' => true], null, $event_data['user_id'] ); // Store in transient for rate limiter to check set_transient("tigerstyle_scent_auto_block_{$client_ip}", time(), DAY_IN_SECONDS); } } /** * 🔐 SECURITY: Get sanitized client information */ private static function get_client_info(): array { return [ 'ip' => self::get_client_ip(), 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown', 'accept_language' => $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '', 'accept_encoding' => $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '', 'referer' => $_SERVER['HTTP_REFERER'] ?? '', 'connection' => $_SERVER['HTTP_CONNECTION'] ?? '', ]; } /** * 🔐 SECURITY: Get client IP address */ private static function get_client_ip(): string { $ip_headers = [ 'HTTP_CF_CONNECTING_IP', 'HTTP_X_REAL_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR' ]; foreach ($ip_headers as $header) { if (!empty($_SERVER[$header])) { $ip = $_SERVER[$header]; if (strpos($ip, ',') !== false) { $ip = trim(explode(',', $ip)[0]); } if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { return $ip; } } } return $_SERVER['REMOTE_ADDR'] ?? 'unknown'; } /** * 🔐 SECURITY: Get sanitized request data */ private static function get_sanitized_request_data(): array { return [ 'method' => $_SERVER['REQUEST_METHOD'] ?? '', 'uri' => $_SERVER['REQUEST_URI'] ?? '', 'query_string' => $_SERVER['QUERY_STRING'] ?? '', 'protocol' => $_SERVER['SERVER_PROTOCOL'] ?? '', 'https' => is_ssl(), 'port' => $_SERVER['SERVER_PORT'] ?? '', ]; } /** * 🔐 SECURITY: Get WordPress environment info */ private static function get_wordpress_info(): array { return [ 'wp_version' => get_bloginfo('version'), 'php_version' => PHP_VERSION, 'plugin_version' => TIGERSTYLE_SCENT_VERSION, 'is_admin' => is_admin(), 'is_user_logged_in' => is_user_logged_in(), 'current_user_id' => get_current_user_id(), ]; } /** * 🔐 SECURITY: Get session identifier */ private static function get_session_id(): string { if (session_id()) { return session_id(); } // Create session identifier from request characteristics $session_data = [ self::get_client_ip(), $_SERVER['HTTP_USER_AGENT'] ?? '', $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '', date('Y-m-d H') // Hour-based session ]; return substr(hash('sha256', json_encode($session_data)), 0, 32); } /** * 🔐 SECURITY: Get severity name */ private static function get_severity_name(int $severity): string { switch ($severity) { case self::SEVERITY_LOW: return 'LOW'; case self::SEVERITY_MEDIUM: return 'MEDIUM'; case self::SEVERITY_HIGH: return 'HIGH'; case self::SEVERITY_CRITICAL: return 'CRITICAL'; default: return 'UNKNOWN'; } } /** * 🔐 SECURITY: Get security events from database * * @param array $filters Filtering options * @param int $limit Number of events to retrieve * @param int $offset Offset for pagination * @return array Security events */ public static function get_security_events(array $filters = [], int $limit = 50, int $offset = 0): array { global $wpdb; $table_name = $wpdb->prefix . 'tigerstyle_scent_security_log'; $where_conditions = ['1=1']; $where_values = []; if (!empty($filters['severity'])) { $where_conditions[] = 'severity >= %d'; $where_values[] = $filters['severity']; } if (!empty($filters['event_type'])) { $where_conditions[] = 'event_type = %s'; $where_values[] = $filters['event_type']; } if (!empty($filters['client_ip'])) { $where_conditions[] = 'client_ip = %s'; $where_values[] = $filters['client_ip']; } if (!empty($filters['date_from'])) { $where_conditions[] = 'timestamp >= %s'; $where_values[] = $filters['date_from']; } if (!empty($filters['date_to'])) { $where_conditions[] = 'timestamp <= %s'; $where_values[] = $filters['date_to']; } $where_clause = implode(' AND ', $where_conditions); $query = "SELECT * FROM $table_name WHERE $where_clause ORDER BY timestamp DESC LIMIT %d OFFSET %d"; $where_values[] = $limit; $where_values[] = $offset; if (!empty($where_values)) { $prepared_query = $wpdb->prepare($query, $where_values); } else { $prepared_query = $query; } return $wpdb->get_results($prepared_query, ARRAY_A); } /** * 🔐 SECURITY: Real-time threat analysis with automatic blocking */ private static function perform_threat_analysis(array $event_data): void { $client_ip = $event_data['client_info']['ip']; $event_type = $event_data['event_type']; $severity = $event_data['severity']; // Immediate threat indicators $immediate_threats = [ self::EVENT_INJECTION_ATTEMPT, self::EVENT_SECURITY_VIOLATION ]; if (in_array($event_type, $immediate_threats)) { self::initiate_emergency_response($event_data); return; } // Analyze recent activity patterns $recent_violations = self::get_recent_violations($client_ip, 60); // Last 60 minutes if (count($recent_violations) >= 5) { // Escalate to high severity and trigger auto-block self::escalate_threat_level($event_data, $recent_violations); } // Check for distributed attack patterns self::analyze_distributed_threats($event_data); } /** * 🔐 SECURITY: Enhanced attack pattern analysis */ private static function analyze_attack_patterns(array $event_data): void { $client_ip = $event_data['client_info']['ip']; // Define attack patterns $attack_patterns = [ 'brute_force' => [ 'events' => [self::EVENT_AUTH_FAILURE], 'threshold' => 10, 'window' => 300, // 5 minutes 'action' => 'temporary_block' ], 'rate_limit_abuse' => [ 'events' => [self::EVENT_RATE_LIMIT], 'threshold' => 3, 'window' => 600, // 10 minutes 'action' => 'escalated_block' ], 'validation_bombing' => [ 'events' => [self::EVENT_VALIDATION_FAILURE], 'threshold' => 20, 'window' => 300, // 5 minutes 'action' => 'investigation_required' ] ]; foreach ($attack_patterns as $pattern_name => $pattern) { if (in_array($event_data['event_type'], $pattern['events'])) { $violations = self::get_recent_violations_by_type( $client_ip, $pattern['events'], $pattern['window'] ); if (count($violations) >= $pattern['threshold']) { self::trigger_attack_response($pattern_name, $pattern['action'], $event_data, $violations); } } } } /** * 🔐 SECURITY: Initiate emergency response for critical threats */ private static function initiate_emergency_response(array $event_data): void { $client_ip = $event_data['client_info']['ip']; // Immediate IP blocking self::emergency_block_ip($client_ip, 'Critical security violation detected'); // Send immediate critical alert self::send_critical_security_alert($event_data); // Log emergency response error_log(sprintf( '[TIGERSTYLE SCENT EMERGENCY] Critical threat from IP %s: %s', $client_ip, $event_data['message'] )); } /** * 🔐 SECURITY: Emergency IP blocking */ private static function emergency_block_ip(string $ip, string $reason): void { // Store in transient for immediate effect set_transient("tigerstyle_scent_emergency_block_{$ip}", [ 'blocked_at' => current_time('timestamp'), 'reason' => $reason, 'duration' => 24 * HOUR_IN_SECONDS, // 24 hours 'threat_level' => 'CRITICAL' ], 24 * HOUR_IN_SECONDS); // Trigger WordPress action for external integrations (firewall plugins, etc.) do_action('tigerstyle_scent_emergency_block', $ip, $reason); } /** * 🔐 SECURITY: Enhanced security alerting */ private static function send_security_alert(array $event_data): void { // Skip alerts in development mode unless critical if (defined('WP_DEBUG') && WP_DEBUG && $event_data['severity'] < self::SEVERITY_CRITICAL) { return; } $admin_email = get_option('admin_email'); if (!$admin_email) return; $subject = sprintf( '[%s] %s Security Alert - %s', get_bloginfo('name'), strtoupper($event_data['severity_name']), $event_data['event_type'] ); $message = self::format_security_alert_email($event_data); // Use WordPress mail function with security headers $headers = [ 'Content-Type: text/html; charset=UTF-8', 'X-Priority: 1', 'X-MSMail-Priority: High' ]; wp_mail($admin_email, $subject, $message, $headers); } /** * 🔐 SECURITY: Format security alert email */ private static function format_security_alert_email(array $event_data): string { $threat_level_colors = [ 1 => '#28a745', // Green 2 => '#ffc107', // Yellow 3 => '#fd7e14', // Orange 4 => '#dc3545' // Red ]; $color = $threat_level_colors[$event_data['severity']] ?? '#6c757d'; return sprintf('
Severity: %s
This alert was generated by TigerStyle Scent OAuth2 Security Monitor