安全编码实战示例

安全的登录系统

php 复制代码
<?php
session_start();

// 1. 防暴力破解
function check_login_attempts($username) {
    $attempts = $_SESSION['login_attempts'][$username] ?? 0;
    $last_attempt = $_SESSION['last_attempt'][$username] ?? 0;
    
    // 5次失败后锁定30分钟
    if($attempts >= 5 && (time() - $last_attempt) < 1800) {
        return false;
    }
    return true;
}

// 2. CSRF Token验证
function verify_csrf_token($token) {
    return isset($_SESSION['csrf_token']) && 
           hash_equals($_SESSION['csrf_token'], $token);
}

// 3. 安全的密码验证
function secure_login($username, $password, $csrf_token) {
    // CSRF验证
    if(!verify_csrf_token($csrf_token)) {
        return ['success' => false, 'message' => 'CSRF验证失败'];
    }
    
    // 登录次数检查
    if(!check_login_attempts($username)) {
        return ['success' => false, 'message' => '账户已锁定'];
    }
    
    // 输入验证
    if(!preg_match('/^[a-zA-Z0-9_]{3,20}$/', $username)) {
        return ['success' => false, 'message' => '用户名格式错误'];
    }
    
    // 预编译查询
    global $conn;
    $stmt = $conn->prepare("SELECT id, password FROM users WHERE username = ? LIMIT 1");
    $stmt->bind_param("s", $username);
    $stmt->execute();
    $result = $stmt->get_result();
    
    if($row = $result->fetch_assoc()) {
        // 使用password_verify验证密码
        if(password_verify($password, $row['password'])) {
            // 登录成功,清除失败记录
            unset($_SESSION['login_attempts'][$username]);
            $_SESSION['user_id'] = $row['id'];
            return ['success' => true];
        }
    }
    
    // 登录失败,记录次数
    $_SESSION['login_attempts'][$username] = 
        ($_SESSION['login_attempts'][$username] ?? 0) + 1;
    $_SESSION['last_attempt'][$username] = time();
    
    return ['success' => false, 'message' => '用户名或密码错误'];
}

// 4. 处理登录请求
if($_SERVER['REQUEST_METHOD'] === 'POST') {
    $result = secure_login(
        $_POST['username'] ?? '',
        $_POST['password'] ?? '',
        $_POST['csrf_token'] ?? ''
    );
    
    if($result['success']) {
        header('Location: dashboard.php');
        exit;
    } else {
        $error = htmlspecialchars($result['message']);
    }
}

// 5. 生成新的CSRF Token
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
?>

<!DOCTYPE html>
<html>
<head>
    <title>安全登录</title>
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'">
</head>
<body>
    <?php if(isset($error)): ?>
        <div style="color: red;"><?php echo $error; ?></div>
    <?php endif; ?>
    
    <form method="POST" action="">
        <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
        
        <label>用户名:</label>
        <input type="text" name="username" required pattern="[a-zA-Z0-9_]{3,20}">
        <br>
        
        <label>密码:</label>
        <input type="password" name="password" required>
        <br>
        
        <button type="submit">登录</button>
    </form>
</body>
</html>

安全的命令执行

php 复制代码
<?php
// 不安全的方式
// $output = shell_exec("ping " . $_GET['ip']);

// 安全方式1:白名单验证
function safe_ping($ip) {
    // 验证IP格式
    if(!filter_var($ip, FILTER_VALIDATE_IP)) {
        return "无效的IP地址";
    }
    
    // 使用escapeshellarg()转义参数
    $safe_ip = escapeshellarg($ip);
    
    // 限制命令和参数
    if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        $cmd = "ping -n 4 {$safe_ip}";
    } else {
        $cmd = "ping -c 4 {$safe_ip}";
    }
    
    // 执行并返回
    return shell_exec($cmd);
}

// 安全方式2:使用专用函数(更好)
function safe_ping_v2($ip) {
    if(!filter_var($ip, FILTER_VALIDATE_IP)) {
        return "无效的IP地址";
    }
    
    // 使用PHP的socket函数代替系统命令
    $errno = 0;
    $errstr = '';
    $socket = @fsockopen($ip, 80, $errno, $errstr, 5);
    
    if($socket) {
        fclose($socket);
        return "主机 {$ip} 可达";
    } else {
        return "主机 {$ip} 不可达";
    }
}
?>

安全的XSS防护

php 复制代码
<?php
// XSS防护函数库
class XSSProtection {
    // HTML上下文输出
    public static function escapeHTML($string) {
        return htmlspecialchars($string, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    }
    
    // JavaScript上下文输出
    public static function escapeJS($string) {
        return json_encode($string, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
    }
    
    // URL上下文输出
    public static function escapeURL($string) {
        return rawurlencode($string);
    }
    
    // 富文本过滤(允许部分HTML)
    public static function filterRichText($html) {
        // 使用HTMLPurifier库
        require_once 'HTMLPurifier.auto.php';
        $config = HTMLPurifier_Config::createDefault();
        $purifier = new HTMLPurifier($config);
        return $purifier->purify($html);
    }
}

// 使用示例
$username = $_GET['name'] ?? '';

// HTML上下文
echo "<div>欢迎 " . XSSProtection::escapeHTML($username) . "</div>";

// JavaScript上下文
echo "<script>var username = " . XSSProtection::escapeJS($username) . ";</script>";

// URL上下文
echo "<a href='profile.php?user=" . XSSProtection::escapeURL($username) . "'>个人资料</a>";
?>

安全的CSRF防护

php 复制代码
<?php
// CSRF防护类
class CSRFProtection {
    // 生成Token
    public static function generateToken() {
        if(!isset($_SESSION['csrf_token'])) {
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        }
        return $_SESSION['csrf_token'];
    }
    
    // 验证Token
    public static function verifyToken($token) {
        if(!isset($_SESSION['csrf_token'])) {
            return false;
        }
        return hash_equals($_SESSION['csrf_token'], $token);
    }
    
    // 生成表单字段
    public static function tokenField() {
        $token = self::generateToken();
        return '<input type="hidden" name="csrf_token" value="' . $token . '">';
    }
    
    // 检查并验证(中间件模式)
    public static function protect() {
        if($_SERVER['REQUEST_METHOD'] === 'POST') {
            $token = $_POST['csrf_token'] ?? '';
            if(!self::verifyToken($token)) {
                http_response_code(403);
                die('CSRF Token验证失败');
            }
        }
    }
}

// 使用示例
session_start();
CSRFProtection::protect();  // 在所有POST处理前调用

// 表单中使用
?>
<form method="POST">
    <?php echo CSRFProtection::tokenField(); ?>
    <input type="text" name="data">
    <button type="submit">提交</button>
</form>
相关推荐
氦客9 小时前
Android Compose : 传统View在Compose组件中的等价物
android·compose·jetpack·对比·传统view·等价物·compose组件
神话200910 小时前
Rust 初体验与快速上手指南
android·rust
CheungChunChiu11 小时前
Linux 内核动态打印机制详解
android·linux·服务器·前端·ubuntu
aidou131412 小时前
Android中设置Dialog和自定义布局相同高度
android·dialog·弹窗高度·getwindow
氦客12 小时前
UI编程的发展史 : 结合命令式UI和声明式UI
android·compose·声明式ui·ui编程·命令式ui·ui编程发展史·标记语言
ISACA中国13 小时前
2026年网络安全与AI趋势预测
人工智能·安全·web安全
Ares-Wang14 小时前
网络》》以太网交换安全
网络·安全
aidou131414 小时前
Android中RecyclerView实现多级列表
android·recyclerview·多级列表·layoutmanager
青风行14 小时前
Android从入门到进阶
android