安全编码实战示例

安全的登录系统

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>
相关推荐
Ln5x9qZC21 小时前
Laravel AI SDK 正式发布
android·人工智能·laravel
小陈工1 小时前
Python Web开发入门(十二):使用Flask-RESTful构建API——让后端开发更优雅
开发语言·前端·python·安全·oracle·flask·restful
Echo-J2 小时前
WinDbg 双机调试(调试机为Windows11系统,被调试机为Windows7系统)
安全·网络安全·云计算·系统安全
南湖北漠2 小时前
记录生活中的一件小事(佚名整理)
网络·人工智能·计算机网络·其他·安全·生活
huwuhang2 小时前
跨平台电子书阅读器 | Readest最新版 安卓版+PC版全平台
android·前端·javascript
云栖梦泽3 小时前
【AI】AI安全工具:AI模型安全检测工具的实战使用
人工智能·安全·机器学习
IeE1QQ3GT3 小时前
FastAPI + SQLite:从基础CRUD到安全并发的实战指南
安全·sqlite·fastapi
KC2703 小时前
大模型提示词注入攻击与防御:当你的 AI 开始“不听话“
人工智能·安全·aigc
Gse0a362g3 小时前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
android·开发语言·php
十六年开源服务商3 小时前
WordPress服务器响应时间优化终极指南2026
android·运维·服务器