クロスサイト リクエスト フォージェリ (CSRF) は、攻撃者が認証されたユーザーをだまして、現在ログインしている Web サイト上で望ましくないアクションを実行させる Web セキュリティの脆弱性です。この攻撃は、Web サイトが持つ信頼を悪用することによって機能します。ユーザーのブラウザで。
これが最も一般的な方法です。実装方法は次のとおりです:
// 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 中国語 Web サイトの他の関連記事を参照してください。