CSRF(Cross-Site Request Forgery)攻擊者誘導已登入用戶在不知情下向目標站點發送惡意請求。本文透過完整範例示範 Token 驗證機制的實作細節與最佳實踐。
bank.com,瀏覽器儲存 Session Cookie。evil.com。evil.com 內嵌表單或圖片自動提交至 bank.com/transfer?to=attacker&amount=1000。伺服器生成唯一、不可預測的 Token,存入 Session 並輸出至表單隱藏欄位。提交時比對 Session 與表單 Token 是否一致。
<?php
session_start();
// 產生 Token:時間戳 + 隨機鹽值雜湊
$token_time = time();
$token = hash_hmac('sha256', $token_time . 'secret_salt', 'site_secret_key');
// 存入 Session
$_SESSION['csrf_token'] = $token;
$_SESSION['csrf_time'] = $token_time;
$expire_time = 600; // 10 分鐘有效
?>
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>CSRF Demo</title></head>
<body>
<form method="post" action="process.php">
<input type="text" name="amount" placeholder="金額">
<input type="hidden" name="csrf_token" value="<?php echo $token; ?>">
<input type="hidden" name="csrf_time" value="<?php echo $token_time; ?>">
<button type="submit">送出</button>
</form>
</body>
</html>
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$token = $_POST['csrf_token'] ?? '';
$token_time = (int)($_POST['csrf_time'] ?? 0);
$expire = 600;
// 1. 檢查時效
if (time() - $token_time > $expire) {
die('Token 已過期,請重新整理頁面。');
}
// 2. 比對 Token(使用 hash_equals 防止時序攻擊)
$expected = $_SESSION['csrf_token'] ?? '';
if (!hash_equals($expected, $token)) {
die('CSRF 驗證失敗,請求來源非法。');
}
// 3. 驗證通過,執行業務邏輯
echo "轉帳成功!金額:{$_POST['amount']}";
// 4. 銷毀 Token(一次性使用)
unset($_SESSION['csrf_token'], $_SESSION['csrf_time']);
}
?>
| 策略 | 說明 | 適用場景 |
|---|---|---|
| SameSite Cookie | 設定 Set-Cookie: ...; SameSite=Strict/Lax,瀏覽器自動阻擋跨站請求攜帶 Cookie | 現代瀏覽器,最簡單有效 |
| 雙重 Cookie 驗證 | Token 同時存 Cookie 與表單,JS 讀取 Cookie 送 Header | API/SPA 架構 |
| 自定義請求標頭 | 要求 X-Requested-With: XMLHttpRequest,簡單 AJAX 保護 | 傳統 jQuery AJAX |
| 驗證碼/再次確認密碼 | 高風險操作(修改密碼、轉帳)二次驗證 | 關鍵業務 |
md5(time()) 產生 Tokenrandom_bytes()、hash_hmac())。== 比對字串hash_equals()。@csrf Blade 指令自動處理。{:token()} 模板標籤 + 控制器 $this->checkToken()。$this->security->get_csrf_hash() + 設定 $config['csrf_protection'] = TRUE;。CsrfGuard 中介層,統一攔截非 GET 請求驗證。CSRF 防禦的核心在於「請求來源驗證」。Token 機制雖經典,但需注意隨機性、時效性、一次性與安全比對。現代專案應優先啟用 SameSite Cookie,輔以 Token 雙重保險,構建纵深防禦體系。