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

PHP CSRF 跨站請求偽造防禦:Crumb 令牌機制完整實現

     編輯:PHP 相關知識

CSRF 攻擊原理

瀏覽器自動攜帶 Cookie 發起請求的特性,使攻擊者可構造惡意頁面,誘導已登錄用戶訪問,在用戶不知情情況下發起敏感操作(轉賬、修改密碼、發帖等)。

Crumb 令牌防禦機制

核心思想:服務端生成不可預測的令牌,表單提交時攜帶,服務端驗證令牌有效性。

Crumb 類實現

<?php
class Crumb {
    const SALT = 'your-secret-salt-change-in-production'; // 必須修改為強隨機密鑰
    static $ttl = 7200; // 令牌有效期 2 小時

    // HMAC-MD5 簽名
    static public function challenge($data) {
        return hash_hmac('md5', $data, self::SALT);
    }

    // 生成令牌
    static public function issueCrumb($uid, $action = -1) {
        $i = ceil(time() / self::$ttl); // 時間窗口
        return substr(self::challenge($i . $action . $uid), -12, 10);
    }

    // 驗證令牌(允許前一時間窗口,應對邊界情況)
    static public function verifyCrumb($uid, $crumb, $action = -1) {
        $i = ceil(time() / self::$ttl);
        $current = substr(self::challenge($i . $action . $uid), -12, 10);
        $prev = substr(self::challenge(($i - 1) . $action . $uid), -12, 10);
        return ($crumb === $current || $crumb === $prev);
    }
}
?>

應用示例

表單頁面嵌入令牌

<form method="post" action="demo.php">
    <input type="hidden" name="crumb" value="<?php echo Crumb::issueCrumb($uid)?>">
    <input type="text" name="content">
    <input type="submit">
</form>

處理頁面驗證令牌

<?php
if (Crumb::verifyCrumb($uid, $_POST['crumb'])) {
    // 令牌有效,正常處理業務邏輯
} else {
    // 令牌無效,拒絕請求並提示錯誤
    die('CSRF 令牌驗證失敗,請重新提交。');
}
?>

關鍵安全要點

  • SALT 必須保密、高強度:使用 random_bytes(32) 生成,存儲在配置文件,不入庫、不輸出
  • 綁定用戶與操作:$uid 標識用戶,$action 區分業務(登錄、轉賬、發帖等),防止令牌跨用戶/跨操作復用
  • 時間窗口機制:$ttl 限制令牌有效期,驗證時兼容前一窗口,平衡安全與用戶體驗
  • 敏感操作強制驗證:修改密碼、綁定手機、轉賬等高風險操作必須驗證 Crumb
  • 避免使用 $_REQUEST:明確區分 $_POST、$_GET,防止參數污染繞過驗證
  • JSON API 同樣需要防護:在請求頭或請求體中傳遞 Crumb,服務端中間件統一驗證

進階防禦:SameSite Cookie

// PHP 7.3+ 原生支持
setcookie('session_id', $value, [
    'expires' => time() + 3600,
    'path' => '/',
    'domain' => '',
    'secure' => true,      // 僅 HTTPS
    'httponly' => true,    // 禁止 JS 讀取
    'samesite' => 'Strict' // 或 'Lax',瀏覽器級 CSRF 防護
]);

SameSite=Strict 完全阻止跨站請求攜帶 Cookie,Lax 允許鏈接跳轉 GET 請求。配合 Crumb 令牌構建雙重防線。

總結

CSRF 防禦的核心是請求唯一性驗證。Crumb 令牌機制通過 HMAC 簽名、時間窗口、用戶/操作綁定,提供輕量級、高強度的防護。現代應用應結合 SameSite Cookie、雙重提交 Cookie 模式、自定義請求頭驗證等多層手段,構建纵深防禦體系。

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