CSRF在PHP中的防御機(jī)制有哪些

PHP
小樊
84
2024-09-12 15:47:21

在 PHP 中,防御 CSRF(跨站請(qǐng)求偽造)攻擊的主要方法包括以下幾種:

  1. 使用 CSRF Token:為每個(gè)表單生成一個(gè)隨機(jī)的 CSRF Token,并將其存儲(chǔ)在用戶(hù)的會(huì)話(huà)中。當(dāng)用戶(hù)提交表單時(shí),需要同時(shí)提交這個(gè) Token,然后在服務(wù)器端進(jìn)行驗(yàn)證。如果 Token 不匹配或者不存在,則拒絕請(qǐng)求。
// 生成 CSRF Token
session_start();
$csrf_token = bin2hex(random_bytes(32));
$_SESSION['csrf_token'] = $csrf_token;

// 在表單中添加隱藏字段
echo '<form action="submit.php" method="post">';
echo<input type="hidden" name="csrf_token" value="' . $csrf_token . '">';
// 其他表單字段...
echo '</form>';

// 驗(yàn)證 CSRF Token
if (isset($_POST['csrf_token']) && $_POST['csrf_token'] === $_SESSION['csrf_token']) {
    // 處理表單數(shù)據(jù)
} else {
    // 阻止請(qǐng)求
    echo "Invalid CSRF Token!";
}
  1. 驗(yàn)證 Referer 頭部:檢查 HTTP 請(qǐng)求的 Referer 頭部,確保請(qǐng)求是從可信任的源發(fā)起的。這種方法有一定的局限性,因?yàn)?Referer 頭部可以被偽造或遺漏。
$allowed_origins = ['https://example.com', 'https://subdomain.example.com'];
$referer = isset($_SERVER['HTTP_REFERER']) ? parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) : '';

if (in_array($referer, $allowed_origins)) {
    // 處理請(qǐng)求
} else {
    // 阻止請(qǐng)求
    echo "Invalid referer!";
}
  1. 使用 SameSite Cookies 屬性:通過(guò)設(shè)置 Cookie 的 SameSite 屬性為 Strict 或 Lax,可以防止瀏覽器在跨站點(diǎn)請(qǐng)求時(shí)發(fā)送 Cookie。這樣,當(dāng)用戶(hù)訪(fǎng)問(wèn)第三方網(wǎng)站時(shí),攻擊者無(wú)法利用用戶(hù)的 Cookie 發(fā)起 CSRF 攻擊。
setcookie('name', 'value', [
    'expires' => time() + 60 * 60 * 24 * 30,
    'path' => '/',
    'domain' => 'example.com',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict', // 或 'Lax'
]);
  1. 用戶(hù)交互確認(rèn):對(duì)于一些敏感操作,如轉(zhuǎn)賬、修改密碼或刪除賬戶(hù)等,可以通過(guò)增加用戶(hù)交互步驟(如確認(rèn)彈窗、輸入驗(yàn)證碼或者二次認(rèn)證來(lái)進(jìn)行操作確認(rèn))降低 CSRF 攻擊的風(fēng)險(xiǎn)。

結(jié)合以上方法,可以有效地防御 CSRF 攻擊。但請(qǐng)注意,沒(méi)有絕對(duì)安全的系統(tǒng),始終保持警惕和更新防御措施是非常重要的。

0