次の方法でCSRFを完全に防ぎ、すべてのユーザーと互換性があるのではないかと思います。
ここにあります:
フォームには、次のような追加のパラメータを含めるだけですencrypted(user's userID + request time)
。サーバー側は復号化して、それが正しいuserIDであり、リクエスト時間がかなり最近のものであることを確認します。
誰かがユーザーのトラフィックを盗聴したり、暗号化を破ったりすることを除けば、これは完全に安全ですか?欠点はありますか?
あなたのアプローチは安全ですが、それは標準ではありません。CSRF攻撃を防ぐ標準的な方法は、隠しフィールドとCookieに含める疑似乱数を生成し、サーバー側で両方の値が一致することを確認することです。この投稿を見てください。
大きな欠点の1つは、ユーザーがフォームを投稿する前に合理的であると判断した時間枠よりも長くブラウザを開いたままにすると、ページが「タイムアウト」することです。私は、アクションが本質的に時間に敏感でない限り、サイトがユーザーを急いでアクションをコミットさせないことを好みます。
攻撃側のサイトがユーザーIDを推測する可能性があるため、完全に安全ではありません。
セッションごとの暗号化キーを使用する場合、それは安全です。(しかし、あなたがする必要があるのは生の鍵を送ることだけであり、それはすでに安全です)
また、タイムゾーンと不正確な時計についても覚えておいてください。
はい、動作するはずです。新しいユーザーを作成するときは、単純な増分番号ではなく、乱数を使用することをお勧めします(もちろん、ユーザーを作成するときは一意であることを確認してください)。そうすれば、攻撃者が「推測」するのは困難です。
UserIDとDateTimeを持つことは始まりですが、カナリアトークンに加えてエントロピーが高いことが望ましい疑似乱数値も必要です。基本的に、特定のコンテキストのページでトークンの予測可能性を下げる必要があります。UserIDとDateTimeだけを持つことは、「十分にランダム」ではないため、理論的にはしばらくすると中断する可能性があります。そうは言っても、CSRF攻撃は一般にスクリプト化されており、直接監視されないため、アプリケーションの露出によっては十分な場合があります。
また、アプリケーションのセキュリティに十分なビットのキーと疑似ランダム初期化ベクトルを使用して、 Rijndael/AESなどのより安全な暗号化アルゴリズムを使用してください。
あなたが提案したセキュリティシステムは攻撃に対して脆弱です。
AESのようなブロック暗号は、非常に安全な乱数ジェネレーターとして一般的に使用されています。それらはCSPRNGと呼ばれます。ただし、他の乱数ジェネレーターと同様に、アルゴリズムに何をシードするかについて心配する必要があります。この場合user's userID + request time
、攻撃者が知ることができる両方を使用していますが、実装にはキーまたはIVがないため、これらはNULLであると想定しています。攻撃者はリクエストを作成しているので、攻撃者は常にを知っていrequest time
ます。これuserId
が主キーである可能性があります。100人のユーザーがいる場合、攻撃者は100個のリクエストを偽造する可能性があり、そのうちの1つが機能します。ただし、攻撃者は管理者にパスワードの変更を強制したい場合があります。通常、管理者の主キーは1です。
whealを再発明しないでください。非常に優れた乱数ジェネレーターがすでに構築されており、アンチcsrfライブラリもあります。