提供されているコードのように、問題はトークン生成方法に起因すると考えられます。予測とエントロピーの欠如に対して脆弱です。この方法は、1 回限りの使用およびフォームごとのトークン検証にも不十分です。
トークン生成を安全なトークン生成に置き換えます。 PHP 7 または PHP 5.3 のメソッド:
session_start();
if (empty($_SESSION['token'])) {
$_SESSION['token'] = bin2hex(random_bytes(32));
}
$token = $_SESSION['token'];
session_start();
if (空($_SESSION['トークン'])) {
if (function_exists('mcrypt_create_iv')) { $_SESSION['token'] = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); } else { $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32)); }
}
$token = $_SESSION['token'];
hash_equals() を使用してトークンを検証する安全に:
if (!empty($_POST['token'])) {
if (hash_equals($_SESSION['token'], $_POST['token'])) { // Proceed to process the form data } else { // Log this as a warning and keep an eye on these attempts }
}
トークンを特定の形式にさらに制限するには、hash_hmac():
echo hash_hmac('sha256', '/my_form.php', $_SESSION['second_token']);
?>" />
Twig テンプレートを使用している場合は、簡略化されたデュアル戦略を使用できます。実装:
$twigEnv->addFunction(
new \Twig_SimpleFunction( 'form_token', function($lock_to = null) { if (empty($_SESSION['token'])) { $_SESSION['token'] = bin2hex(random_bytes(32)); } if (empty($_SESSION['token2'])) { $_SESSION['token2'] = random_bytes(32); } if (empty($lock_to)) { return $_SESSION['token']; } return hash_hmac('sha256', $lock_to, $_SESSION['token2']); } )
);
この関数を使用すると、安全な一般トークンを次のように使用できます。
フォームごとのトークンは次の方法で生成できます:
使い捨てトークンの要件については、次のような専用ライブラリの使用を検討してください。 Paragon Initiative Enterprises の反 CSRF ライブラリ。
以上がAJAX および標準フォームで使用すると、CSRF トークンが時々空になるのはなぜですか? PHP でこれを修正するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。