説明
パスワード再設定トークンをuniqid、rand、mt_randなどの予測可能な値で作ると、攻撃者が再設定リンクやコードを推測できるおそれがあります。十分なエントロピーを持つ、暗号学的に安全な乱数を使用する必要があります。
想定される影響
- パスワード再設定リンクの推測
- アカウントの乗っ取り
- 再設定コードの推測が成功する可能性の増加
対処方法
bin2hex(random_bytes(32))など、暗号学的に安全な乱数でトークンを生成してください。- トークンはハッシュ化して保存し、短い有効期限と1回限りの使用を適用してください。
- 再設定リンクのドメインは、リクエストのHostヘッダーではなく、信頼できる設定から取得してください。
例
savePasswordResetToken()は、ユーザーごとのトークンハッシュと有効期限を保存するアプリケーション関数であり、実装は省略しています。再設定処理ではハッシュと期限を検証し、使用済みトークンを再利用できないようにする必要があります。
変更前
php
<?php
$resetToken = uniqid();
mail($email, 'Password reset', 'Use token ' . $resetToken);
変更後
php
<?php
$resetToken = bin2hex(random_bytes(32));
$tokenHash = hash('sha256', $resetToken);
savePasswordResetToken($userId, $tokenHash, time() + 900);
mail($email, 'Password reset', 'Use token ' . $resetToken);
説明:
- 変更前: 予測可能な値を再設定トークンに使うため、攻撃者がリンクやコードを推測できるおそれがあります。
- 変更後: 暗号学的に安全な乱数で再設定トークンを生成し、そのハッシュと短い有効期限をサーバーへ保存します。