App下載

PHP防御CSRF攻擊:保護(hù)應(yīng)用免受威脅

愛(ài)嘯的女孩超愛(ài)看你笑 2024-02-02 10:58:36 瀏覽數(shù) (1371)
反饋

隨著 Web 應(yīng)用程序的發(fā)展和普及,網(wǎng)絡(luò)安全問(wèn)題變得越來(lái)越重要。跨站請(qǐng)求偽造(CSRF)攻擊成為了其中一種常見(jiàn)的攻擊手段。CSRF攻擊是指攻擊者通過(guò)仿冒合法用戶的請(qǐng)求來(lái)執(zhí)行一些惡意操作,例如在用戶沒(méi)有意識(shí)到的情況下轉(zhuǎn)賬、修改密碼等。為了保護(hù)用戶和 Web 應(yīng)用程序的安全,開(kāi)發(fā)者需要采取措施來(lái)防御此類攻擊。本文將介紹如何使用 PHP 來(lái)防御CSRF攻擊。

什么是CSRF?

CSRF,全稱為Cross-Site Request Forgery(跨站請(qǐng)求偽造),是一種常見(jiàn)的網(wǎng)絡(luò)安全漏洞和攻擊方式。它利用了Web應(yīng)用程序中的信任機(jī)制,通過(guò)欺騙用戶在已登錄的狀態(tài)下執(zhí)行非意愿的操作,從而導(dǎo)致未經(jīng)授權(quán)的請(qǐng)求被發(fā)送到目標(biāo)網(wǎng)站。

Snipaste_2024-02-02_10-56-26

CSRF攻擊的基本原理

  1. 用戶在已登錄的狀態(tài)下訪問(wèn)惡意網(wǎng)站或點(diǎn)擊惡意鏈接。
  2. 惡意網(wǎng)站或鏈接中包含了對(duì)目標(biāo)網(wǎng)站的請(qǐng)求,該請(qǐng)求可能是修改用戶個(gè)人信息、進(jìn)行資金轉(zhuǎn)賬、刪除數(shù)據(jù)等未經(jīng)授權(quán)的操作。
  3. 用戶的瀏覽器會(huì)自動(dòng)發(fā)送該請(qǐng)求,因?yàn)橛脩粢呀?jīng)在目標(biāo)網(wǎng)站中登錄并保留了有效的身份驗(yàn)證憑證(如Cookie)。
  4. 目標(biāo)網(wǎng)站接收到請(qǐng)求后,無(wú)法分辨這是來(lái)自用戶的合法請(qǐng)求還是惡意請(qǐng)求,并按照請(qǐng)求執(zhí)行了相應(yīng)的操作。

csrf-attack-1

生成和驗(yàn)證CSRF令牌

生成CSRF令牌
session_start();
$token = bin2hex(random_bytes(32)); // 生成32個(gè)字節(jié)的隨機(jī)令牌
$_SESSION['csrf_token'] = $token; // 將令牌存儲(chǔ)在會(huì)話中
在表單中嵌入CSRF令牌
<form action="process.php" method="POST">
  <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
  <!-- 其他表單字段 -->
  <button type="submit">提交</button>
</form>
驗(yàn)證CSRF令牌
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    // 令牌驗(yàn)證失敗,執(zhí)行相應(yīng)的錯(cuò)誤處理
    die("CSRF攻擊檢測(cè)到!請(qǐng)求被拒絕。");
  }
  // 令牌驗(yàn)證成功,繼續(xù)處理請(qǐng)求
}

同源檢測(cè)

檢查請(qǐng)求的來(lái)源頭部

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $referer = $_SERVER['HTTP_REFERER'];
  $origin = $_SERVER['HTTP_ORIGIN'];
  
  $allowedOrigins = array('https://example.com', 'https://www.example.com'); // 允許的合法來(lái)源
  
  if (!in_array($referer, $allowedOrigins) || !in_array($origin, $allowedOrigins)) {
    // 來(lái)源驗(yàn)證失敗,執(zhí)行相應(yīng)的錯(cuò)誤處理
    die("CSRF攻擊檢測(cè)到!請(qǐng)求被拒絕。");
  }
  // 來(lái)源驗(yàn)證成功,繼續(xù)處理請(qǐng)求
}

添加驗(yàn)證碼

生成和驗(yàn)證驗(yàn)證碼
session_start();
$randomNumber = rand(1000, 9999); // 生成隨機(jī)驗(yàn)證碼
$_SESSION['captcha'] = $randomNumber; // 將驗(yàn)證碼存儲(chǔ)在會(huì)話中

// 在表單中顯示驗(yàn)證碼圖像
<img src="captcha.php" alt="驗(yàn)證碼">

// 驗(yàn)證用戶輸入的驗(yàn)證碼
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  if (!isset($_POST['captcha']) || $_POST['captcha'] !== $_SESSION['captcha']) {
    // 驗(yàn)證碼驗(yàn)證失敗,執(zhí)行相應(yīng)的錯(cuò)誤處理
    die("驗(yàn)證碼驗(yàn)證失?。≌?qǐng)求被拒絕。");
  }
  // 驗(yàn)證碼驗(yàn)證成功,繼續(xù)處理請(qǐng)求
}

設(shè)置HTTP頭部

設(shè)置SameSite屬性為Strict或Lax
header('Set-Cookie: mycookie=value; SameSite=Strict');

header('Set-Cookie: mycookie=value; SameSite=Lax');

總結(jié)

保護(hù)PHP應(yīng)用免受CSRF攻擊是至關(guān)重要的安全措施。通過(guò)生成和驗(yàn)證CSRF令牌、進(jìn)行同源檢測(cè)、添加驗(yàn)證碼、設(shè)置HTTP頭部和使用安全框架等方法,可以防止惡意用戶利用CSRF攻擊來(lái)執(zhí)行未經(jīng)授權(quán)的操作。開(kāi)發(fā)人員應(yīng)該根據(jù)具體應(yīng)用的需求和安全級(jí)別選擇合適的防御措施,并定期審查和更新這些措施,以確保應(yīng)用的安全性。通過(guò)采取適當(dāng)?shù)腃SRF防御措施,可以防止?jié)撛诘陌踩{,保護(hù)用戶和應(yīng)用的數(shù)據(jù)安全。


PHP

0 人點(diǎn)贊