1

そこで、すべてのフォームに自動的に挿入するクラスを作成しました。<input type="hidden" name="csrf" value="csrf_value_uniq_id" />

今私の問題は、5分後にキーが期限切れになるように設定したことですが、ページにとどまるか、戻ってきてフォームを送信するときに食べに行くと、csrfキーが一致しません。

これで 24 時間で有効期限が切れるように設定できますが、意図したとおりに安全かどうかはわかりません。投稿フォームで使用しています。

では、これを行うにはどうすればよいですか?

4

2 に答える 2

1

サーバー側の状態を必要とせず、タイムアウトを必要としないソリューションは、署名されたトークンです。フォームに含めるランダムな値を作成し、そのトークンに自分だけが知っている秘密で署名します。

$secret    = 'weufiwu93tu2b248hg24';
$token     = uniqid('', true);
$signature = sha1($secret . ':' . $token);

次に、トークンと署名をフォームに埋め込みます。フォームを再度受信したら、フォームからのトークンを使用して操作を繰り返し、SHA1(secret:token)結果をフォームからの署名と比較します。適切に選択されたランダムな秘密と堅牢なハッシュがある場合、秘密を知っている人以外は誰もトークンに署名できないため、トークンがあなたからのものであることが証明されます。

さらに、トークンの有効性を制限するためにフォーム/署名にタイムスタンプを含めることができます (5 分より長くしますが、トークンを永久に使用できるほど長くはしません)。ユーザー ID は、トークンを特定のユーザー、フォームフィールドインジェクションから保護するために予想されるフォームフィールド、およびチェックしたいその他のもの。例えば:

signature = SHA1(secret:token:timestamp:userid:[form_field_name[:...]])

上記の署名の場合、署名、トークン、タイムスタンプ、および明らかにフォーム フィールドをフォームに埋め込みます。送信時に、送信されたタイムスタンプが特定のウィンドウ内にあることを確認し、サーバーからシークレットとユーザー ID を取得し、それらすべての部分で署名を再作成し、送信された署名と照合します。

上記のコードは単なる例であることに注意してください。トークンはランダム性のより良いソースを使用し、より長くする必要があり、ハッシュ関数は HMAC や bcrypt のようなより堅牢なものにする必要があります。これはアイデアを伝えるためのものであり、実装の詳細ではありません。


実際の実装はKunststube\CSRFPにあります。とにかくそのようなものが必要だったので、この質問に答えてこれをまとめました。

于 2012-11-08T17:29:27.130 に答える
1

攻撃者が有効なトークンを取得するには、次の 2 つの方法が考えられます。

  1. 彼はトークンを推測/予測することができます、または
  2. 彼はクライアントからそれを取得できます。

前者は、十分なエントロピーを持つ適切なランダム ソースを使用することで軽減できます。後者は、送信を保護し (つまり、HTTPS)、ユーザーのトークンを取得するために使用できるクロスサイト スクリプティングなどの攻撃から保護することによって確立できます。

両方を行うと、有効期限が切れないようにすることもできます (またはユーザーのセッションの終了時)。

于 2012-11-08T17:37:43.430 に答える