0, 'blocked_ips' => 0, 'suspicious_registrations' => 0, 'file_upload_blocks' => 0 ]; // Count blocked IPs $transients = $wpdb->get_results( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '_transient_king_addons_%_attempts_%' AND option_value >= 3" ); $stats['blocked_ips'] = count($transients); // Get failed attempts from error log (simplified - would need actual log parsing) $log_file = ini_get('error_log'); if ($log_file && file_exists($log_file)) { $log_content = file_get_contents($log_file); $stats['failed_logins_24h'] = substr_count($log_content, 'King Addons Security: Failed login'); $stats['suspicious_registrations'] = substr_count($log_content, 'Suspicious registration pattern'); $stats['file_upload_blocks'] = substr_count($log_content, 'File upload blocked'); } return $stats; } /** * Get currently blocked IPs */ private static function get_blocked_ips() { global $wpdb; $blocked_ips = []; $transients = $wpdb->get_results( "SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name LIKE '_transient_king_addons_%_attempts_%'" ); foreach ($transients as $transient) { $attempts = intval($transient->option_value); if ($attempts >= Security_Manager::MAX_LOGIN_ATTEMPTS) { // Extract IP from transient name preg_match('/_transient_king_addons_\w+_attempts_(.+)/', $transient->option_name, $matches); if (isset($matches[1])) { $ip_hash = $matches[1]; // Get expiration time $timeout_option = '_transient_timeout_' . str_replace('_transient_', '', $transient->option_name); $expires = get_option($timeout_option, 0); $blocked_ips[] = [ 'ip' => 'IP Hash: ' . substr($ip_hash, 0, 8) . '...', // Don't expose full IPs 'attempts' => $attempts, 'last_attempt' => time() - 300, // Approximate 'expires' => $expires ]; } } } return $blocked_ips; } /** * Get recent failed attempts from logs */ private static function get_recent_failed_attempts() { $attempts = []; // This would parse actual log files in a real implementation // For now, return sample data structure return $attempts; } /** * AJAX handler to clear security logs */ public static function clear_security_logs() { if (!wp_verify_nonce($_POST['nonce'], 'king_addons_security_nonce')) { wp_send_json_error(['message' => 'Invalid nonce']); } if (!current_user_can('manage_options')) { wp_send_json_error(['message' => 'Insufficient permissions']); } // Clear all rate limiting transients global $wpdb; $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_king_addons_%_attempts_%' OR option_name LIKE '_transient_timeout_king_addons_%_attempts_%'" ); wp_send_json_success(['message' => 'Security logs cleared successfully']); } /** * AJAX handler to unblock IP */ public static function unblock_ip() { if (!wp_verify_nonce($_POST['nonce'], 'king_addons_security_nonce')) { wp_send_json_error(['message' => 'Invalid nonce']); } if (!current_user_can('manage_options')) { wp_send_json_error(['message' => 'Insufficient permissions']); } $ip = sanitize_text_field($_POST['ip']); if (empty($ip)) { wp_send_json_error(['message' => 'Invalid IP address']); } // Clear attempts for this IP (simplified) global $wpdb; $ip_hash = md5($ip); $wpdb->query($wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s", '%_king_addons_%_attempts_' . $ip_hash, '%_king_addons_%_attempts_' . $ip_hash . '%' )); wp_send_json_success(['message' => 'IP unblocked successfully']); } /** * AJAX handler to export security report */ public static function export_security_report() { if (!wp_verify_nonce($_POST['nonce'], 'king_addons_security_nonce')) { wp_send_json_error(['message' => 'Invalid nonce']); } if (!current_user_can('manage_options')) { wp_send_json_error(['message' => 'Insufficient permissions']); } // Generate security report $stats = self::get_security_statistics(); $blocked_ips = self::get_blocked_ips(); $report = [ 'generated_at' => current_time('Y-m-d H:i:s'), 'site_url' => get_site_url(), 'plugin_version' => defined('KING_ADDONS_VERSION') ? KING_ADDONS_VERSION : 'Unknown', 'statistics' => $stats, 'blocked_ips' => $blocked_ips, 'security_settings' => [ 'max_login_attempts' => get_option('king_addons_max_login_attempts', 5), 'lockout_duration' => get_option('king_addons_lockout_duration', 15), 'security_logging_enabled' => get_option('king_addons_enable_security_logging', 1), ] ]; // Convert to JSON $json_report = json_encode($report, JSON_PRETTY_PRINT); // Create filename $filename = 'king-addons-security-report-' . date('Y-m-d-H-i-s') . '.json'; // Return download URL $upload_dir = wp_upload_dir(); $report_path = $upload_dir['path'] . '/' . $filename; // Save file if (file_put_contents($report_path, $json_report)) { $download_url = $upload_dir['url'] . '/' . $filename; wp_send_json_success([ 'message' => 'Security report generated successfully', 'download_url' => $download_url, 'filename' => $filename ]); } else { wp_send_json_error(['message' => 'Failed to generate report file']); } } }