セキュリティコードについては、この方法でトークンを生成しないでください。 $token = md5(uniqid(rand(), TRUE));
これを試してください:
CSRFトークンの生成
PHP 7
session_start();
if (empty($_SESSION['token'])) {
$_SESSION['token'] = bin2hex(random_bytes(32));
}
$token = $_SESSION['token'];
追記:一、私の雇用者のオープンソースプロジェクトは、バックポートへの取り組みですrandom_bytes()
し、random_int()
PHP 5プロジェクトに。これはMITライセンスで、GithubおよびComposerでparagonie / random_compatとして利用できます。
PHP 5.3以降(またはext-mcryptを使用)
session_start();
if (empty($_SESSION['token'])) {
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'];
CSRFトークンの確認
を使用し==
たり===
、使用したりしないでくださいhash_equals()
(PHP 5.6+のみですが、以前のバージョンのhash-compatライブラリで使用できます)。
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()
。HMACは特定のキー付きハッシュ関数であり、弱いハッシュ関数(MD5など)を使用しても安全です。ただし、代わりにハッシュ関数のSHA-2ファミリーを使用することをお勧めします。
まず、HMACキーとして使用する2番目のトークンを生成し、次のようなロジックを使用してレンダリングします。
<input type="hidden" name="token" value="<?php
echo hash_hmac('sha256', '/my_form.php', $_SESSION['second_token']);
?>" />
そして、トークンを検証するときに合同操作を使用します:
$calc = hash_hmac('sha256', '/my_form.php', $_SESSION['second_token']);
if (hash_equals($calc, $_POST['token'])) {
// Continue...
}
あるフォームに対して生成されたトークンは、知らないうちに別のコンテキストで再利用することはできません$_SESSION['second_token']
。ページにドロップしたトークンとは別のトークンをHMACキーとして使用することが重要です。
ボーナス:ハイブリッドアプローチ+ Twig統合
Twigテンプレートエンジンを使用する人は誰でも、このフィルターを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']);
}
)
);
このTwig関数を使用すると、次のように両方の汎用トークンを使用できます。
<input type="hidden" name="token" value="{{ form_token() }}" />
またはロックダウンされたバリアント:
<input type="hidden" name="token" value="{{ form_token('/my_form.php') }}" />
Twigはテンプレートのレンダリングのみに関係しています。それでも、トークンを適切に検証する必要があります。私の意見では、Twig戦略は、最大限のセキュリティの可能性を維持しながら、柔軟性とシンプルさを向上させます。
使い捨てCSRFトークン
各CSRFトークンを1回だけ使用できるというセキュリティ要件がある場合は、検証が成功するたびに、最も簡単な戦略でトークンを再生成します。ただし、これを行うと以前のトークンがすべて無効になるため、一度に複数のタブを閲覧するユーザーとうまく混合できません。
Paragon Initiative Enterprisesは、これらのコーナーケース用のAnti-CSRFライブラリを維持しています。1回限りのフォームごとのトークンでのみ機能します。十分なトークンがセッションデータに格納されている場合(デフォルトの構成:65535)、最初に未使用の最も古いトークンが循環します。
token_time
に使うの?