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

PHP 防止偽造 URL 提交:Referer 檢查與 AJAX 方案對比

     編輯:PHP 綜合知識

方案一:HTTP Referer 檢查(基礎防禦)

function CheckURL() {
    $serverName = $_SERVER['SERVER_NAME'];
    $referer    = $_SERVER['HTTP_REFERER'] ?? '';

    // 解析 referer 主機部分
    $urlParts = parse_url($referer);
    $refHost  = $urlParts['host'] ?? '';

    if (strcasecmp($refHost, $serverName) !== 0) {
        die('警告!檢測到站外提交,請求被攔截。');
    }
}

局限性

  • 瀏覽器可不發送/偽造 Referer
  • 隱私模式/安全軟件可能剝離 Referer
  • 同域名下惡意頁面(如論壇發帖帶鏈接)可繞過
  • HTTPS → HTTP 請求不攜帶 Referer

方案二:POST + 隱藏字段(提升門檻)

<form method="post" action="/vote">
    <input type="hidden" name="token" value="">
    <input type="hidden" name="item_id" value="123">
    <button type="submit">投票</button>
</form>

服務端驗證 $_POST['token'] 有效性(Session/Redis 存儲、一次性、過期時間)。

方案三:AJAX 提交(同源策略保護)

// 原生 XMLHttpRequest 封裝
function createXHR() {
    if (window.XMLHttpRequest) return new XMLHttpRequest();
    if (window.ActiveXObject) {
        const versions = ['MSXML2.XmlHttp.6.0', 'MSXML2.XmlHttp.3.0'];
        for (const v of versions) {
            try { return new ActiveXObject(v); } catch(e) {}
        }
    }
    throw new Error('瀏覽器不支持 AJAX');
}

function ajaxPost(url, data = '') {
    const xhr = createXHR();
    xhr.open('POST', url, false); // 同步演示,生產用異步
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status !== 200) console.error('請求失敗');
    };
    xhr.send(data);
}

// 使用
ajaxPost('/vote', 'item_id=123&token=' + getTokenFromMeta());

AJAX 優勢

  • 受瀏覽器同源策略保護,跨域請求默認被攔截(需 CORS 許可)
  • 可在 Header 傳遞自定義 Token(如 X-CSRF-Token)
  • 不刷新頁面,用戶體驗佳

方案四:綜合防禦體系(生產級推薦)

  1. CSRF Token:所有狀態改變操作(POST/PUT/DELETE)強制驗證
  2. SameSite Cookie:Set-Cookie: session=...; SameSite=Strict 防攜帶 Cookie 跨站請求
  3. 雙重驗證:敏感操作(支付、刪除)需二次確認(密碼/短信/郵箱驗證碼)
  4. Referer 輔助:作為第二層檢查,非核心依賴
  5. 頻率限制:IP/用戶級限流,防刷接口
  6. 內容安全策略 CSP:限制腳本來源,降低 XSS 風險

代碼層面最佳實踐

// 中間件/基類控制器統一攔截
protected function verifyRequest() {
    if ($this->request->isPost()) {
        // 1. CSRF Token
        if (!hash_equals(session('csrf_token'), $this->request->post('token'))) {
            $this->fail('Token 無效');
        }
        // 2. 可選 Referer
        if (config('check_referer') && ! $this->checkReferer()) {
            $this->fail('非法來源');
        }
    }
    // 3. 刷新 Token(可選)
    session('csrf_token', bin2hex(random_bytes(32)));
}

總結

Referer 檢查不可靠,CSRF Token + SameSite Cookie 是現代 Web 防偽造提交的標準組合。AJAX 利用同源策略提升門檻,但不能替代服務端 Token 驗證。分層防禦才是王道。

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