跨站請求偽造 (CSRF) 是一種網路安全漏洞,攻擊者可以利用該漏洞誘騙經過身份驗證的用戶在他們目前登入的網站上執行不需要的操作。此攻擊透過利用網站所擁有的信任來進行在使用者的瀏覽器中。
這是最常用的方法。實作方法如下:
// In your session initialization (e.g., at login) session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } // In your form function generateFormWithCSRFToken() { return '<form method="POST" action="/submit"> <input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '"> <!-- rest of your form fields --> <input type="submit" value="Submit"> </form>'; } // In your form processing function validateCSRFToken() { if (!isset($_POST['csrf_token']) || !isset($_SESSION['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) { die('CSRF token validation failed'); } return true; }
此方法使用帶有自訂標頭的 AJAX 請求:
// PHP Backend session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } // Validate the token if ($_SERVER['REQUEST_METHOD'] === 'POST') { $headers = getallheaders(); if (!isset($headers['X-CSRF-Token']) || !hash_equals($_SESSION['csrf_token'], $headers['X-CSRF-Token'])) { http_response_code(403); die('CSRF token validation failed'); } } // JavaScript Frontend const csrfToken = '<?php echo $_SESSION["csrf_token"]; ?>'; fetch('/api/endpoint', { method: 'POST', headers: { 'X-CSRF-Token': csrfToken, 'Content-Type': 'application/json' }, body: JSON.stringify(data) });
此方法涉及將令牌作為 cookie 和請求參數發送:
// Set both cookie and session token session_start(); $token = bin2hex(random_bytes(32)); $_SESSION['csrf_token'] = $token; setcookie('csrf_token', $token, [ 'httponly' => true, 'secure' => true, 'samesite' => 'Strict' ]); // Validation function function validateDoubleSubmitToken() { if (!isset($_COOKIE['csrf_token']) || !isset($_POST['csrf_token']) || !isset($_SESSION['csrf_token'])) { return false; } return hash_equals($_COOKIE['csrf_token'], $_POST['csrf_token']) && hash_equals($_SESSION['csrf_token'], $_POST['csrf_token']); }
現代應用程式也可以使用 SameSite cookie 屬性作為附加保護層:
// Set cookie with SameSite attribute session_start(); session_set_cookie_params([ 'lifetime' => 0, 'path' => '/', 'domain' => $_SERVER['HTTP_HOST'], 'secure' => true, 'httponly' => true, 'samesite' => 'Strict' ]);
function generateSecureToken($length = 32) { return bin2hex(random_bytes($length)); }
function validateToken($userToken, $storedToken) { if (empty($userToken) || empty($storedToken)) { return false; } return hash_equals($storedToken, $userToken); }
class CSRFProtection { public static function getTokenField() { return sprintf( '<input type="hidden" name="csrf_token" value="%s">', htmlspecialchars($_SESSION['csrf_token']) ); } }
許多 PHP 框架提供內建的 CSRF 保護:
// In your session initialization (e.g., at login) session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } // In your form function generateFormWithCSRFToken() { return '<form method="POST" action="/submit"> <input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '"> <!-- rest of your form fields --> <input type="submit" value="Submit"> </form>'; } // In your form processing function validateCSRFToken() { if (!isset($_POST['csrf_token']) || !isset($_SESSION['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) { die('CSRF token validation failed'); } return true; }
// PHP Backend session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } // Validate the token if ($_SERVER['REQUEST_METHOD'] === 'POST') { $headers = getallheaders(); if (!isset($headers['X-CSRF-Token']) || !hash_equals($_SESSION['csrf_token'], $headers['X-CSRF-Token'])) { http_response_code(403); die('CSRF token validation failed'); } } // JavaScript Frontend const csrfToken = '<?php echo $_SESSION["csrf_token"]; ?>'; fetch('/api/endpoint', { method: 'POST', headers: { 'X-CSRF-Token': csrfToken, 'Content-Type': 'application/json' }, body: JSON.stringify(data) });
CSRF 保護對於 Web 應用程式安全至關重要。雖然實現 CSRF 保護的方法有多種,但使用隱藏表單欄位的基於令牌的方法仍然是使用最廣泛、最可靠的方法。請記住結合不同的保護方法以增強安全性,並在 PHP 應用程式中實施 CSRF 保護時始終遵循安全最佳實踐。
請記住,CSRF 保護應該是更廣泛的安全策略的一部分,其中包括適當的會話管理、安全性 cookie 處理和輸入驗證。
以上是PHP 中的 CSRF 保護的詳細內容。更多資訊請關注PHP中文網其他相關文章!