首页 / 跨境电商轻量软件 / 实操指南:构建安全用户认证接口的5个重要原则

实操指南:构建安全用户认证接口的5个重要原则

实操指南:构建安全用户认证接口的5个重要原则

引言:为什么用户认证安全如此重要?

在当今数字化时代,用户认证系统是任何Web应用的第一道安全防线。据统计,超过80%的数据泄露事件与弱认证机制有关。对于基于WordPress的网站和应用来说,用户认证不仅是保护管理员后台的关键,更是保障用户数据安全的核心。

WordPress作为全球使用最广泛的CMS系统,其默认认证机制虽然基础可靠,但在面对日益复杂的网络攻击时,往往需要开发者进行强化和定制。本指南将基于WordPress代码开发,为行业新人和程序员提供构建安全用户认证接口的五个重要原则,帮助您打造坚不可摧的用户认证系统。

原则一:实施强密码策略与安全存储

1.1 WordPress密码机制解析

WordPress默认使用PHP的password_hash()函数进行密码哈希处理,采用bcrypt算法。这是当前行业标准,但我们可以进一步强化:

// WordPress核心密码验证函数示例
function wp_check_password($password, $hash, $user_id = '') {
    global $wp_hasher;
    
    if (empty($hash)) {
        return false;
    }
    
    // 检查是否为旧版MD5哈希
    if (strlen($hash) <= 32) {
        $check = hash_equals($hash, md5($password));
        if ($check && $user_id) {
            // 重新哈希为更安全的格式
            wp_set_password($password, $user_id);
        }
        return $check;
    }
    
    // 使用现代哈希验证
    if (empty($wp_hasher)) {
        require_once ABSPATH . WPINC . '/class-phpass.php';
        $wp_hasher = new PasswordHash(8, true);
    }
    
    return $wp_hasher->CheckPassword($password, $hash);
}

1.2 强化密码策略实施

在WordPress中实施强密码策略:

// 在主题的functions.php或自定义插件中添加
add_filter('wp_authenticate_user', 'enforce_strong_password_policy', 10, 2);

function enforce_strong_password_policy($user, $password) {
    // 密码最小长度检查
    if (strlen($password) < 12) {
        return new WP_Error('weak_password', 
            __('密码必须至少包含12个字符。', 'textdomain'));
    }
    
    // 密码复杂性检查
    if (!preg_match('/[A-Z]/', $password) || 
        !preg_match('/[a-z]/', $password) || 
        !preg_match('/[0-9]/', $password) || 
        !preg_match('/[^A-Za-z0-9]/', $password)) {
        return new WP_Error('weak_password',
            __('密码必须包含大写字母、小写字母、数字和特殊字符。', 'textdomain'));
    }
    
    // 检查常见弱密码
    $weak_passwords = ['password', '123456', 'qwerty', 'admin123'];
    if (in_array(strtolower($password), $weak_passwords)) {
        return new WP_Error('weak_password',
            __('您使用的密码太常见,请选择更复杂的密码。', 'textdomain'));
    }
    
    return $user;
}

1.3 密码哈希升级策略

确保始终使用最新的哈希算法:

// 定期检查并升级密码哈希
add_action('wp_login', 'check_password_hash_strength', 10, 2);

function check_password_hash_strength($user_login, $user) {
    // 检查当前哈希算法是否需要升级
    if (password_needs_rehash($user->user_pass, PASSWORD_ARGON2ID)) {
        // 这里不直接更新,而是标记需要更新
        update_user_meta($user->ID, 'needs_password_rehash', true);
    }
}

原则二:实现多因素认证(MFA)

2.1 WordPress多因素认证基础

多因素认证是当前企业级安全标准。以下是在WordPress中实现TOTP(基于时间的一次性密码)的示例:

// 为用户启用TOTP功能
add_action('show_user_profile', 'add_2fa_settings_field');
add_action('edit_user_profile', 'add_2fa_settings_field');

function add_2fa_settings_field($user) {
    if (!current_user_can('manage_options')) {
        return;
    }
    
    $is_2fa_enabled = get_user_meta($user->ID, '2fa_enabled', true);
    $2fa_secret = get_user_meta($user->ID, '2fa_secret', true);
    
    if (empty($2fa_secret)) {
        $2fa_secret = generate_2fa_secret();
        update_user_meta($user->ID, '2fa_secret', $2fa_secret);
    }
    
    ?>
    <h3><?php _e('双因素认证', 'textdomain'); ?></h3>
    <table class="form-table">
        <tr>
            <th><?php _e('启用双因素认证', 'textdomain'); ?></th>
            <td>
                <label for="2fa_enabled">
                    <input type="checkbox" name="2fa_enabled" id="2fa_enabled" 
                           value="1" <?php checked($is_2fa_enabled, 1); ?> />
                    <?php _e('启用Google Authenticator双因素认证', 'textdomain'); ?>
                </label>
                <?php if ($is_2fa_enabled && $2fa_secret): ?>
                <p class="description">
                    <?php _e('扫描二维码或输入密钥设置验证器:', 'textdomain'); ?><br>
                    <strong><?php echo chunk_split($2fa_secret, 4, ' '); ?></strong>
                </p>
                <?php endif; ?>
            </td>
        </tr>
    </table>
    <?php
}

2.2 TOTP验证实现

// 验证TOTP代码
function verify_2fa_code($user_id, $code) {
    $secret = get_user_meta($user_id, '2fa_secret', true);
    
    if (empty($secret)) {
        return false;
    }
    
    require_once ABSPATH . 'wp-content/plugins/your-plugin/lib/phpotp/Token.php';
    
    $token = new Token($secret);
    $timestamp = time();
    
    // 允许前后30秒的时间窗口
    return $token->verify($code, $timestamp, 1);
}

// 在登录过程中集成2FA验证
add_filter('authenticate', 'integrate_2fa_authentication', 30, 3);

function integrate_2fa_authentication($user, $username, $password) {
    if (is_wp_error($user) || !$user) {
        return $user;
    }
    
    $is_2fa_enabled = get_user_meta($user->ID, '2fa_enabled', true);
    
    if (!$is_2fa_enabled) {
        return $user;
    }
    
    // 检查是否已提供2FA代码
    if (empty($_POST['2fa_code'])) {
        // 重定向到2FA验证页面
        wp_redirect(add_query_arg('2fa_required', $user->ID, wp_login_url()));
        exit;
    }
    
    if (!verify_2fa_code($user->ID, $_POST['2fa_code'])) {
        return new WP_Error('invalid_2fa', 
            __('双因素认证代码无效。', 'textdomain'));
    }
    
    return $user;
}

2.3 备用验证码和恢复选项

// 生成备用验证码
function generate_backup_codes($user_id) {
    $codes = [];
    for ($i = 0; $i < 10; $i++) {
        $codes[] = bin2hex(random_bytes(4)); // 8位十六进制代码
    }
    
    // 哈希存储备用码
    $hashed_codes = array_map('wp_hash_password', $codes);
    update_user_meta($user_id, '2fa_backup_codes', $hashed_codes);
    
    // 返回明文代码供用户保存(仅显示一次)
    return $codes;
}

// 验证备用码
function verify_backup_code($user_id, $code) {
    $hashed_codes = get_user_meta($user_id, '2fa_backup_codes', true);
    
    if (empty($hashed_codes)) {
        return false;
    }
    
    foreach ($hashed_codes as $index => $hashed_code) {
        if (wp_check_password($code, $hashed_code)) {
            // 使用后移除该备用码
            unset($hashed_codes[$index]);
            update_user_meta($user_id, '2fa_backup_codes', array_values($hashed_codes));
            return true;
        }
    }
    
    return false;
}

原则三:防范暴力破解与自动化攻击

3.1 登录尝试限制

// 记录登录尝试
add_action('wp_login_failed', 'track_failed_login_attempt');

function track_failed_login_attempt($username) {
    $ip_address = $_SERVER['REMOTE_ADDR'];
    $transient_key = 'failed_login_' . md5($ip_address . $username);
    
    $attempts = get_transient($transient_key);
    $attempts = $attempts ? $attempts + 1 : 1;
    
    // 存储15分钟
    set_transient($transient_key, $attempts, 15 * MINUTE_IN_SECONDS);
    
    // 如果尝试次数过多,锁定账户
    if ($attempts >= 5) {
        $lockout_key = 'login_lockout_' . md5($ip_address);
        set_transient($lockout_key, true, 30 * MINUTE_IN_SECONDS);
        
        // 记录安全日志
        log_security_event('brute_force_attempt', [
            'ip' => $ip_address,
            'username' => $username,
            'attempts' => $attempts,
            'timestamp' => current_time('mysql')
        ]);
    }
}

// 检查登录锁定
add_filter('authenticate', 'check_login_lockout', 5, 3);

function check_login_lockout($user, $username, $password) {
    $ip_address = $_SERVER['REMOTE_ADDR'];
    $lockout_key = 'login_lockout_' . md5($ip_address);
    
    if (get_transient($lockout_key)) {
        return new WP_Error('login_lockout',
            __('由于多次登录失败,该IP已被暂时锁定。请30分钟后再试。', 'textdomain'));
    }
    
    return $user;
}

3.2 验证码集成

// 在登录表单添加验证码
add_action('login_form', 'add_login_captcha');

function add_login_captcha() {
    // 简单的数学验证码
    $num1 = rand(1, 10);
    $num2 = rand(1, 10);
    $_SESSION['captcha_answer'] = $num1 + $num2;
    
    echo '<p>
        <label for="captcha">' . sprintf(__('请计算: %d + %d = ?', 'textdomain'), $num1, $num2) . '<br>
        <input type="text" name="captcha" id="captcha" class="input" value="" size="20"></label>
    </p>';
}

// 验证验证码
add_filter('authenticate', 'verify_login_captcha', 20, 3);

function verify_login_captcha($user, $username, $password) {
    if (empty($_POST['captcha']) || $_POST['captcha'] != $_SESSION['captcha_answer']) {
        return new WP_Error('invalid_captcha',
            __('验证码错误。', 'textdomain'));
    }
    
    return $user;
}

3.3 基于行为的异常检测

// 检测异常登录行为
add_action('wp_login', 'detect_anomalous_login', 10, 2);

function detect_anomalous_login($user_login, $user) {
    $current_ip = $_SERVER['REMOTE_ADDR'];
    $user_agent = $_SERVER['HTTP_USER_AGENT'];
    $known_ips = get_user_meta($user->ID, 'known_login_ips', true);
    $known_devices = get_user_meta($user->ID, 'known_devices', true);
    
    if (empty($known_ips)) {
        $known_ips = [];
    }
    
    if (empty($known_devices)) {
        $known_devices = [];
    }
    
    $device_fingerprint = md5($user_agent . $_SERVER['HTTP_ACCEPT_LANGUAGE']);
    
    // 检查是否为新的IP地址或设备
    if (!in_array($current_ip, $known_ips) || !in_array($device_fingerprint, $known_devices)) {
        // 发送通知邮件
        $admin_email = get_option('admin_email');
        $subject = sprintf(__('异常登录检测 - %s', 'textdomain'), get_bloginfo('name'));
        $message = sprintf(__(
            '检测到用户 %s 的异常登录:nn' .
            '时间:%sn' .
            'IP地址:%sn' .
            '用户代理:%sn' .
            '如果是您本人的操作,请忽略此邮件。', 'textdomain'),
            $user_login,
            current_time('mysql'),
            $current_ip,
            $user_agent
        );
        
        wp_mail($admin_email, $subject, $message);
        
        // 记录新的IP和设备
        if (!in_array($current_ip, $known_ips)) {
            $known_ips[] = $current_ip;
            update_user_meta($user->ID, 'known_login_ips', $known_ips);
        }
        
        if (!in_array($device_fingerprint, $known_devices)) {
            $known_devices[] = $device_fingerprint;
            update_user_meta($user->ID, 'known_devices', $known_devices);
        }
    }
}

原则四:安全的会话管理

4.1 WordPress会话强化

// 增强WordPress会话安全性
add_action('init', 'enhance_session_security', 1);

function enhance_session_security() {
    if (session_status() === PHP_SESSION_NONE) {
        // 使用安全的会话配置
        ini_set('session.cookie_httponly', 1);
        ini_set('session.cookie_secure', is_ssl() ? 1 : 0);
        ini_set('session.cookie_samesite', 'Strict');
        ini_set('session.use_strict_mode', 1);
        ini_set('session.cookie_lifetime', 0); // 浏览器关闭时过期
        
        session_start();
    }
}

// 自定义会话管理
class Secure_Session_Handler {
    private $table_name;
    
    public function __construct() {
        global $wpdb;
        $this->table_name = $wpdb->prefix . 'secure_sessions';
        
        // 创建会话存储表
        $this->create_table();
        
        // 设置自定义会话处理器
        session_set_save_handler(
            [$this, 'open'],
            [$this, 'close'],
            [$this, 'read'],
            [$this, 'write'],
            [$this, 'destroy'],
            [$this, 'gc']
        );
    }
    
    private function create_table() {
        global $wpdb;
        
        $charset_collate = $wpdb->get_charset_collate();
        
        $sql = "CREATE TABLE IF NOT EXISTS {$this->table_name} (
            session_id varchar(255) NOT NULL,
            session_data longtext NOT NULL,
            user_id bigint(20) unsigned DEFAULT NULL,
            ip_address varchar(45) DEFAULT NULL,
            user_agent text,
            last_activity datetime NOT NULL,
            PRIMARY KEY (session_id),
            KEY user_id (user_id),
            KEY last_activity (last_activity)
        ) $charset_collate;";
        
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        dbDelta($sql);
    }
    
    public function read($session_id) {
        global $wpdb;
        
        $session = $wpdb->get_var($wpdb->prepare(
            "SELECT session_data FROM {$this->table_name} WHERE session_id = %s",
            $session_id
        ));
        
        return $session ?: '';
    }
    
    public function write($session_id, $session_data) {
        global $wpdb, $current_user;
        
        $data = [
            'session_id' => $session_id,
            'session_data' => $session_data,
            'user_id' => $current_user->ID ?: null,
            'ip_address' => $_SERVER['REMOTE_ADDR'],
            'user_agent' => $_SERVER['HTTP_USER_AGENT'],
            'last_activity' => current_time('mysql')
        ];
        
        $wpdb->replace($this->table_name, $data);
        
        return true;
    }
}

// 初始化安全会话处理器
new Secure_Session_Handler();

4.2 会话固定攻击防护

// 防止会话固定攻击
add_action('wp_login', 'regenerate_session_on_login', 10, 2);

function regenerate_session_on_login($user_login, $user) {
    // 登录时重新生成会话ID
    session_regenerate_id(true);
    
    // 将用户ID与会话关联
    $_SESSION['user_id'] = $user->ID;
    $_SESSION['login_time'] = time();
    $_SESSION['login_ip'] = $_SERVER['REMOTE_ADDR'];
}

// 验证会话一致性
add_action('init', 'validate_session_integrity');

function validate_session_integrity() {
    if (is_user_logged_in()) {
        $current_user = wp_get_current_user();
        
        // 检查会话中的用户ID是否与当前用户匹配
        if (isset($_SESSION['user_id']) && $_SESSION['user_id'] != $current_user->ID) {
            wp_logout();
            wp_redirect(wp_login_url());
            exit;
        }

4.3 会话超时与并发控制

// 实现会话超时管理
add_action('init', 'manage_session_timeout');

function manage_session_timeout() {
    if (!is_user_logged_in()) {
        return;
    }
    
    $inactivity_timeout = 30 * MINUTE_IN_SECONDS; // 30分钟无操作超时
    $absolute_timeout = 12 * HOUR_IN_SECONDS; // 12小时绝对超时
    
    // 检查会话最后活动时间
    if (isset($_SESSION['last_activity']) && 
        (time() - $_SESSION['last_activity']) > $inactivity_timeout) {
        // 会话超时,强制登出
        wp_logout();
        wp_redirect(add_query_arg('session_expired', '1', wp_login_url()));
        exit;
    }
    
    // 检查绝对超时
    if (isset($_SESSION['login_time']) && 
        (time() - $_SESSION['login_time']) > $absolute_timeout) {
        wp_logout();
        wp_redirect(add_query_arg('session_expired', '1', wp_login_url()));
        exit;
    }
    
    // 更新最后活动时间
    $_SESSION['last_activity'] = time();
}

// 并发会话控制
add_action('wp_login', 'enforce_concurrent_session_limit', 10, 2);

function enforce_concurrent_session_limit($user_login, $user) {
    $max_concurrent_sessions = 3; // 最大并发会话数
    
    global $wpdb;
    $table_name = $wpdb->prefix . 'secure_sessions';
    
    // 获取用户当前活跃会话
    $active_sessions = $wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM {$table_name} 
         WHERE user_id = %d AND last_activity > %s",
        $user->ID,
        date('Y-m-d H:i:s', time() - (30 * MINUTE_IN_SECONDS))
    ));
    
    // 如果超过限制,终止最早的会话
    if ($active_sessions >= $max_concurrent_sessions) {
        $oldest_session = $wpdb->get_var($wpdb->prepare(
            "SELECT session_id FROM {$table_name} 
             WHERE user_id = %d 
             ORDER BY last_activity ASC LIMIT 1",
            $user->ID
        ));
        
        if ($oldest_session) {
            $wpdb->delete($table_name, ['session_id' => $oldest_session]);
        }
    }
}

// 登出时清理会话
add_action('wp_logout', 'cleanup_user_sessions');

function cleanup_user_sessions() {
    if (isset($_SESSION['user_id'])) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'secure_sessions';
        
        $wpdb->delete($table_name, [
            'user_id' => $_SESSION['user_id'],
            'session_id' => session_id()
        ]);
    }
    
    // 销毁当前会话
    session_destroy();
}

原则五:全面的安全监控与日志记录

5.1 安全事件日志系统

// 创建安全日志表
function create_security_log_table() {
    global $wpdb;
    
    $table_name = $wpdb->prefix . 'security_logs';
    $charset_collate = $wpdb->get_charset_collate();
    
    $sql = "CREATE TABLE IF NOT EXISTS {$table_name} (
        id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
        event_type varchar(100) NOT NULL,
        user_id bigint(20) unsigned DEFAULT NULL,
        username varchar(255) DEFAULT NULL,
        ip_address varchar(45) DEFAULT NULL,
        user_agent text,
        details longtext,
        severity enum('low','medium','high','critical') DEFAULT 'low',
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY event_type (event_type),
        KEY user_id (user_id),
        KEY ip_address (ip_address),
        KEY created_at (created_at),
        KEY severity (severity)
    ) $charset_collate;";
    
    require_once ABSPATH . 'wp-admin/includes/upgrade.php';
    dbDelta($sql);
}

register_activation_hook(__FILE__, 'create_security_log_table');

// 安全日志记录函数
function log_security_event($event_type, $data = []) {
    global $wpdb, $current_user;
    
    $table_name = $wpdb->prefix . 'security_logs';
    
    $log_data = [
        'event_type' => $event_type,
        'user_id' => $current_user->ID ?? null,
        'username' => $current_user->user_login ?? null,
        'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0',
        'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
        'details' => json_encode($data, JSON_UNESCAPED_UNICODE),
        'severity' => determine_event_severity($event_type),
        'created_at' => current_time('mysql')
    ];
    
    $wpdb->insert($table_name, $log_data);
    
    // 高严重性事件实时通知
    if (in_array($log_data['severity'], ['high', 'critical'])) {
        send_security_alert($event_type, $data);
    }
}

// 确定事件严重性
function determine_event_severity($event_type) {
    $severity_map = [
        'login_success' => 'low',
        'login_failed' => 'medium',
        'brute_force_attempt' => 'high',
        'password_changed' => 'medium',
        'role_changed' => 'high',
        'suspicious_activity' => 'critical',
        'file_tamper_detected' => 'critical'
    ];
    
    return $severity_map[$event_type] ?? 'low';
}

// 关键安全事件钩子
add_action('wp_login', 'log_successful_login', 10, 2);
add_action('wp_login_failed', 'log_failed_login');
add_action('password_reset', 'log_password_reset', 10, 2);
add_action('set_user_role', 'log_role_change', 10, 3);

function log_successful_login($user_login, $user) {
    log_security_event('login_success', [
        'username' => $user_login,
        'user_id' => $user->ID,
        'login_time' => current_time('mysql')
    ]);
}

function log_failed_login($username) {
    log_security_event('login_failed', [
        'attempted_username' => $username,
        'ip_address' => $_SERVER['REMOTE_ADDR']
    ]);
}

function log_password_reset($user, $new_pass) {
    log_security_event('password_changed', [
        'user_id' => $user->ID,
        'username' => $user->user_login,
        'changed_by' => get_current_user_id()
    ]);
}

function log_role_change($user_id, $role, $old_roles) {
    log_security_event('role_changed', [
        'user_id' => $user_id,
        'new_role' => $role,
        'old_roles' => $old_roles,
        'changed_by' => get_current_user_id()
    ]);
}

5.2 实时安全监控与告警

// 实时安全监控类
class Security_Monitor {
    private $alert_thresholds = [
        'failed_logins' => 5, // 5次失败登录
        'suspicious_ips' => 3, // 3个不同账户
        'rapid_requests' => 100 // 100次/分钟
    ];
    
    private $request_counts = [];
    
    public function __construct() {
        add_action('init', [$this, 'monitor_request_rate']);
        add_action('wp_login_failed', [$this, 'analyze_login_patterns']);
        add_action('shutdown', [$this, 'cleanup_monitoring_data']);
    }
    
    // 监控请求频率
    public function monitor_request_rate() {
        $ip = $_SERVER['REMOTE_ADDR'];
        $current_minute = floor(time() / 60);
        
        if (!isset($this->request_counts[$ip])) {
            $this->request_counts[$ip] = [];
        }
        
        if (!isset($this->request_counts[$ip][$current_minute])) {
            $this->request_counts[$ip][$current_minute] = 0;
        }
        
        $this->request_counts[$ip][$current_minute]++;
        
        // 检查是否超过阈值
        if ($this->request_counts[$ip][$current_minute] > $this->alert_thresholds['rapid_requests']) {
            $this->trigger_rate_limit($ip);
        }
    }
    
    // 分析登录模式
    public function analyze_login_patterns($username) {
        global $wpdb;
        
        $ip = $_SERVER['REMOTE_ADDR'];
        $table_name = $wpdb->prefix . 'security_logs';
        
        // 检查同一IP尝试的不同用户名数量
        $unique_usernames = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(DISTINCT username) FROM {$table_name} 
             WHERE ip_address = %s 
             AND event_type = 'login_failed' 
             AND created_at > DATE_SUB(NOW(), INTERVAL 1 HOUR)",
            $ip
        ));
        
        if ($unique_usernames >= $this->alert_thresholds['suspicious_ips']) {
            log_security_event('suspicious_activity', [
                'type' => 'multiple_account_attempts',
                'ip' => $ip,
                'unique_usernames' => $unique_usernames
            ]);
            
            // 自动阻止该IP
            $this->block_ip_temporarily($ip);
        }
    }
    
    // 触发速率限制
    private function trigger_rate_limit($ip) {
        $block_key = 'rate_limit_block_' . md5($ip);
        set_transient($block_key, true, 15 * MINUTE_IN_SECONDS);
        
        log_security_event('rate_limit_exceeded', [
            'ip' => $ip,
            'requests_per_minute' => $this->request_counts[$ip][floor(time() / 60)]
        ]);
        
        // 返回429 Too Many Requests
        if (!headers_sent()) {
            header('HTTP/1.1 429 Too Many Requests');
            header('Retry-After: 900'); // 15分钟
            exit('请求过于频繁,请稍后再试。');
        }
    }
    
    // 临时阻止IP
    private function block_ip_temporarily($ip) {
        $block_key = 'ip_block_' . md5($ip);
        set_transient($block_key, true, 60 * MINUTE_IN_SECONDS);
        
        // 更新.htaccess或防火墙规则
        $this->update_firewall_rules($ip);
    }
    
    // 清理监控数据
    public function cleanup_monitoring_data() {
        $current_minute = floor(time() / 60);
        $retention_minutes = 5; // 保留5分钟数据
        
        foreach ($this->request_counts as $ip => $minutes) {
            foreach ($minutes as $minute => $count) {
                if ($minute < $current_minute - $retention_minutes) {
                    unset($this->request_counts[$ip][$minute]);
                }
            }
            
            if (empty($this->request_counts[$ip])) {
                unset($this->request_counts[$ip]);
            }
        }
    }
    
    // 更新防火墙规则
    private function update_firewall_rules($ip) {
        $htaccess_path = ABSPATH . '.htaccess';
        
        if (file_exists($htaccess_path) && is_writable($htaccess_path)) {
            $rule = "n# 安全监控自动阻止nDeny from {$ip}n";
            
            $content = file_get_contents($htaccess_path);
            if (strpos($content, $rule) === false) {
                file_put_contents($htaccess_path, $rule, FILE_APPEND);
            }
        }
    }
}

// 初始化安全监控
new Security_Monitor();

5.3 安全报告与审计

// 安全报告生成类
class Security_Reporter {
    
    // 生成每日安全报告
    public function generate_daily_report() {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'security_logs';
        $yesterday = date('Y-m-d', strtotime('-1 day'));
        
        $report_data = [
            'date' => $yesterday,
            'total_events' => 0,
            'by_severity' => [],
            'by_event_type' => [],
            'top_offending_ips' => [],
            'failed_login_attempts' => 0,
            'successful_logins' => 0
        ];
        
        // 获取事件统计
        $results = $wpdb->get_results($wpdb->prepare(
            "SELECT 
                COUNT(*) as count,
                severity,
                event_type,
                ip_address
             FROM {$table_name} 
             WHERE DATE(created_at) = %s 
             GROUP BY severity, event_type, ip_address 
             ORDER BY count DESC",
            $yesterday
        ));
        
        foreach ($results as $row) {
            $report_data['total_events'] += $row->count;
            
            // 按严重性统计
            if (!isset($report_data['by_severity'][$row->severity])) {
                $report_data['by_severity'][$row->severity] = 0;
            }
            $report_data['by_severity'][$row->severity] += $row->count;
            
            // 按事件类型统计
            if (!isset($report_data['by_event_type'][$row->event_type])) {
                $report_data['by_event_type'][$row->event_type] = 0;
            }
            $report_data['by_event_type'][$row->event_type] += $row->count;
            
            // 统计特定事件
            if ($row->event_type === 'login_failed') {
                $report_data['failed_login_attempts'] += $row->count;
            } elseif ($row->event_type === 'login_success') {
                $report_data['successful_logins'] += $row->count;
            }
            
            // 收集攻击IP
            if (in_array($row->event_type, ['login_failed', 'brute_force_attempt', 'suspicious_activity'])) {
                if (!isset($report_data['top_offending_ips'][$row->ip_address])) {
                    $report_data['top_offending_ips'][$row->ip_address] = 0;
                }
                $report_data['top_offending_ips'][$row->ip_address] += $row->count;
            }
        }
        
        // 排序并限制前10个攻击IP
        arsort($report_data['top_offending_ips']);
        $report_data['top_offending_ips'] = array_slice($report_data['top_offending_ips'], 0, 10, true);
        
        return $report_data;
    }
    
    // 发送安全报告
    public function send_security_report($report_data) {
        $admin_email = get_option('admin_email');
        $site_name = get_bloginfo('name');
        
        $subject = sprintf(__('[%s] 每日安全报告 - %s', 'textdomain'), 
            $site_name, 
            $report_data['date']
        );
        
        // 构建报告内容
        $message = $this->format_report_message($report_data);
        
        // 添加HTML版本
        $headers = ['Content-Type: text/html; charset=UTF-8'];
        
        wp_mail($admin_email, $subject, $message, $headers);
    }
    
    // 格式化报告消息
    private function format_report_message($report_data) {
        ob_start();
        ?>
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="UTF-8">
            <style>
                body { font-family: Arial, sans-serif; line-height: 1.6; }
                .report-container { max-width: 800px; margin: 0 auto; }
                .section { margin: 20px 0; padding: 15px; background: #f9f9f9; border-left: 4px solid #0073aa; }
                .critical { border-left-color: #dc3232; }
                .high { border-left-color: #f56e28; }
                .medium { border-left-color: #ffb900; }
                .low { border-left-color: #46b450; }
                table { width: 100%; border-collapse: collapse; }
                th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }
                th { background-color: #f2f2f2; }
            </style>
        </head>
        <body>
            <div class="report-container">
                <h1>安全报告 - <?php echo esc_html($report_data['date']); ?></h1>
                
                <div class="section">
                    <h2>概览</h2>
                    <p>总安全事件: <strong><?php echo esc_html($report_data['total_events']); ?></strong></p>
                    <p>成功登录: <?php echo esc_html($report_data['successful_logins']); ?></p>
                    <p>失败登录尝试: <?php echo esc_html($report_data['failed_login_attempts']); ?></p>
                </div>
                
                <div class="section">
                    <h2>事件严重性分布</h2>
                    <table>
                        <tr>
                            <th>严重性</th>
                            <th>数量</th>
                            <th>百分比</th>
                        </tr>
                        <?php foreach ($report_data['by_severity'] as $severity => $count): ?>
                        <tr class="<?php echo esc_attr($severity); ?>">
                            <td><?php echo esc_html(ucfirst($severity)); ?></td>
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/204.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部