這套系統採用 HTTP Basic Authentication 機制實作使用者認證,包含三個核心模組:認證核心 auth.inc、資料庫連線 connect.inc、錯誤處理 error.inc,以及一個管理介面 usermanage.php 提供啟用/停用/刪除使用者功能。資料庫採用單表 auth 設計,欄位包含帳號、密碼、真實姓名、所屬 realm、啟用狀態。
auth.inc<?php
$id = "xxxCOM";
if(!isset($PHP_AUTH_USER)) {
Header("WWW-Authenticate: Basic realm=\"$id\"");
Header("HTTP/1.0 401 Unauthorized");
require('error.inc');
exit;
}
$name = $PHP_AUTH_USER;
$pass = $PHP_AUTH_PW;
require("connect.inc");
$query = "select * from auth where username='$name' and realm='$id'";
$result = mysql_db_query("admin", $query);
if(mysql_num_rows($result) == 0) {
Header("WWW-Authenticate: Basic realm=\"$id\"");
Header("HTTP/1.0 401 Unauthorized");
require('error.inc');
exit;
}
$active = mysql_result($result,0,"active");
if($active == 'no') {
// 回傳 404 偽裝不存在
?>
<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD><BODY>
<H1>Not Found</H1>...
</BODY></HTML>
<?php exit; ?>
?>
運作流程:
$PHP_AUTH_USER 是否存在(瀏覽器是否送出認證標頭)WWW-Authenticate 標頭觸發瀏覽器彈出登入框connect.inc<?php mysql_connect("localhost", "user", ""); ?>
極簡連線設定,無錯誤處理、無字元集設定、使用根帳號無密碼(極度不安全)。
auth 表CREATE TABLE auth (
id smallint(6) DEFAULT '0' NOT NULL auto_increment,
username varchar(16) DEFAULT '' NOT NULL,
lastname tinyblob,
firstname tinyblob,
password varchar(16),
realm varchar(16),
active char(3),
PRIMARY KEY (id),
UNIQUE id (id),
UNIQUE username (username)
);
使用 tinyblob 儲存姓名(非文字型別)、密碼欄位長度 16 字元(暗示明文或弱雜湊)、active 為 char(3) 儲存 'yes'/'no'。
usermanage.php<?php include("auth.inc"); ?>
<?php
// 雙重驗證:僅允許 admin/mypassword
if ($PHP_AUTH_USER != "admin") { ... 401 ... }
if ($PHP_AUTH_PW != "mypassword") { ... 401 ... }
// 處理啟用/停用/刪除
if ($activate) { UPDATE auth SET active='yes' WHERE id='$id'; }
if ($deactivate) { UPDATE auth SET active='no' WHERE id='$id'; }
if ($delete) { DELETE FROM auth WHERE id='$id'; }
// 顯示使用者列表表格
echo "<table border=1>...";
while ($r = mysql_fetch_array($result)) {
// 產生每列含操作連結:Activate/Deactivate/Delete
}
?>
管理介面另建一組硬編碼帳密 admin/mypassword,與資料庫認證系統分離,邏輯混淆。
| 風險等級 | 問題 | 說明 | 修正方案 |
|---|---|---|---|
| 🔴 致命 | SQL 注入 | 所有查詢直接拼接變數 $name、$id | PDO 預處理語句 |
| 🔴 致命 | 密碼明文/弱雜湊 | varchar(16) 長度暗示 MD5 或明文 | password_hash() + password_verify() |
| 🔴 致命 | HTTP Basic Auth 傳輸明文 | 無 HTTPS 時帳密可被竊聽 | 強制 HTTPS / 改用 Session + 表單登入 |
| 🔴 致命 | 管理介面硬編碼帳密 | admin/mypassword 寫死在程式碼 | 資料庫角色權限控管(RBAC) |
| 🟠 高 | 棄用 mysql_* 函式 | PHP 7+ 不支援 | 遷移至 PDO / MySQLi |
| 🟠 高 | 無 CSRF 保護 | 操作連結為 GET 請求,可被偽造 | POST + CSRF Token |
| 🟡 中 | 錯誤訊息洩露 | die() 直接輸出 SQL 錯誤 | 自訂錯誤頁面、記錄 Log |
| 🟡 中 | 停用帳號回傳 404 | 資訊洩露:帳號存在但被停用 | 統一回傳 401 或通用錯誤訊息 |
// 1. 資料庫遷移(加入鹽值雜湊、角色、建立時間)
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
email VARCHAR(100) UNIQUE,
full_name VARCHAR(100),
role ENUM('admin','user') DEFAULT 'user',
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_login TIMESTAMP NULL
);
// 2. PDO 連線單例
class DB {
private static $pdo;
public static function get() {
if (!self::$pdo) {
self::$pdo = new PDO("mysql:host=localhost;dbname=auth;charset=utf8mb4",
'db_user', 'strong_pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
}
return self::$pdo;
}
}
// 3. 認證服務類
class Auth {
public static function verify($username, $password) {
$stmt = DB::get()->prepare("SELECT * FROM users WHERE username=? AND is_active=1");
$stmt->execute([$username]);
$user = $stmt->fetch();
return $user && password_verify($password, $user['password_hash']) ? $user : false;
}
public static function requireLogin() {
if (!isset($_SERVER['PHP_AUTH_USER'])) {
self::challenge();
}
$user = self::verify($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
if (!$user) self::challenge();
return $user;
}
private static function challenge() {
header('WWW-Authenticate: Basic realm="MyApp"');
header('HTTP/1.0 401 Unauthorized');
exit('Authentication required');
}
}
admin 角色可管理使用者,user 僅能修改自身資料deleted_at 欄位替代硬刪除,支援復原這套系統展示了 HTTP Basic Auth 在 PHP 中的基本應用,但存在多項致命安全缺陷,絕不可直接用於生產環境。現代 Web 應用建議採用 Session/Cookie 基礎的表單登入、JWT 無狀態認證、OAuth2/OpenID Connect 等成熟方案,搭配 HTTPS 強制傳輸加密、密碼強雜湊儲存、完善的權限模型與審計日誌,才能構建安全可靠的認證授權體系。