首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 簡易登入驗證類別:含 SQL 注入風險分析與現代化重構建議

     編輯:PHP 綜合知識

本文展示一個基礎的 checklogin 類別,演示如何封裝帳號密碼驗證、資料庫查詢與 Session 管理。然而,原始碼存在嚴重的 SQL 注入漏洞、使用已移除的 mysql_* 函數、明文密碼比對等安全隱憂。本文在保留教學示範價值的同時,詳細分析風險並提供現代化重構方案。

原始碼風險分析

class checklogin {
    var $name;
    var $pwd;

    function __construct($username, $password) {
        $this->name = $username;
        $this->pwd = $password;
    }

    function checkinput() {
        global $db; // 假設 $db 為資料庫連線物件
        // ⚠️ 直接拼接變數 → SQL 注入高風險
        $sql = "select * from tb_manager where name='$this->name' and pwd='$this->pwd'";
        $res = $db->query($sql);
        $info = $db->fetch_array($res);

        if ($info['name'] == $this->name and $info['pwd'] == $this->pwd) {
            $_SESSION['admin_name'] = $info['name'];
            $_SESSION['pwd'] = $info['pwd']; // ⚠️ 明文密碼存 Session
            echo "";
        } else {
            echo "";
            exit;
        }
    }
}

關鍵安全缺失

問題風險修正方向
字串拼接 SQLSQL 注入,繞過驗證使用 Prepared Statements (參數綁定)
明文密碼存儲/比對資料庫洩露即帳號全失效使用 password_hash() / password_verify()
密碼寫入 SessionSession 劫持即拿到密碼僅存用戶 ID、角色等非敏感資訊
JavaScript 跳轉依賴前端、易被攔截/繞過使用 PHP header('Location: ...')
全域 $db 變數耦合度高、難測試依賴注入 (DI) 傳入連線物件

現代化重構範例 (PDO + 密碼雜湊)

class LoginService {
    private PDO $pdo;

    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }

    public function attempt(string $username, string $password): bool {
        $stmt = $this->pdo->prepare("SELECT id, password_hash FROM users WHERE username = ?");
        $stmt->execute([$username]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($user && password_verify($password, $user['password_hash'])) {
            $_SESSION['user_id'] = $user['id'];
            $_SESSION['username'] = $username;
            // 可選:重新生成 Session ID 防止 fixation
            session_regenerate_id(true);
            return true;
        }
        return false;
    }
}

// 使用方式
$pdo = new PDO("mysql:host=localhost;dbname=app;charset=utf8mb4", 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);

$login = new LoginService($pdo);
if ($login->attempt($_POST['username'] ?? '', $_POST['password'] ?? '')) {
    header('Location: dashboard.php');
    exit;
} else {
    $error = '帳號或密碼錯誤';
}

登入機制是系統安全的第一道關卡,務必採用參數化查詢、強雜湊演算法、最小權限 Session 管理,並定期進行滲透測試與代碼審查。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved