これは見た目ほど単純ではないと思い始めています。ここと「SO」にある多くの「受け入れられた」回答には、それらを批判する別の回答があります。これまでに集めたものです
私が集めたもののほとんどはこれからです SO質問
IPの使用- 不正確
例のために。シンガポールのような国では、ホームユーザーが利用できるISPの数とIPの数が限られています
また、これは分散型ブルートフォース攻撃には効果がないと思います
セッションCookieの使用-簡単に克服でき、Cookieを消去するのに時間がかかりません。また、ブルートフォース攻撃の分散には効果がありません。
ユーザー名の使用-指数関数的に増加するタイムアウト- 回避策
1000個のユーザー名のリストがある場合は、user1 + password1、user2 + pasword1、user3 + password1 ... user1 + password2、user2 + password2を試します
recapchaを使用する-良いですが、それでも同じ「ユーザー」であることを知っておく必要があります(分散攻撃を実行したり、Cookieをクリアしたりできます)。
だから私は完璧なソリューションはないと思いますが、失敗したログイン試行のスロットルを処理するためにOWASPなどの組織によって採用されたかなり「良い」ソリューションはありますか?
私はかつて Merkle's Puzzles に類似したアプローチを使用することを検討しました。たとえば、すべてのログイン試行にワンタイムキーを使用してHMACで署名することを要求できます。たとえば、サーバーは次の方法でパズルを準備できます:-シード(長いランダム値)、-r(任意の範囲内のランダムな整数値)、-キー= PBKDF2(シード、r)
サーバーは次のパズルをクライアントに送信できます:(シード、ハッシュ(キー))。有効なキーを取得するために、クライアントはこのパズルをブルートフォースする必要があります(r値を順番にチェックし、指定されたシードのPBKDF2を計算し、そのハッシュをサーバーから受信したhash(key)と比較します)。クライアントは正しいキーを見つけると、それを使用して1つのログイン試行に署名します。
このアプローチでは、作業量はクライアントとサーバーの間で非対称です(クライアントはより多くの計算を行う必要があります)。さらに、サーバーは選択されたr値から範囲を変更する「作業係数」を調整できます。
もちろん、このスキームはパスワードの総当たり攻撃を防ぐことはできませんが、そのような攻撃のコストは増加します。
おおざっぱなアイデアだと言ったように、実際にどれほどうまくいくかはわかりません。
ブルートフォースパスワードの解読から保護するには、基本的には「ユーザー名の使用-指数関数的に増加するタイムアウト」という用語を使用する必要があります。ユーザー名ごとに、最後に成功したログオン以降の失敗の数と、別のログオン試行が許可される時間の値を記録します。送信されたパスワードを確認する前に、現在の時刻をユーザー名のロックアウト時間と比較します。時間がまだ経過していない場合は、ログオン要求が続行されないようにします。要求を遅らせることでこれを行うことができますが、それらの遅延(サーバーのリソースを占有する)が多すぎると、簡単にDDOS攻撃を受ける可能性があります。そのため、ユーザー名のロックアウトが期限切れになっていない場合は、代わりにhttpステータス429 Too Many Requestsで返信してください。ログオンがこれを超えて続行できるようになり、パスワードが失敗するたびに、ユーザー名の失敗カウントがインクリメントされ、それに基づいて、ロックアウト時間が現在の時間と失敗カウントに基づく指数関数的な遅延に設定されます。ログオンが成功すると、失敗カウントとロックアウト時間がリセットされます。
表示される「回避策」は特に問題ではありません。 1000個のユーザー名のリストが順番に試行されるか、並行して試行されるかに関係なく、各ユーザー名には独自のロックアウト時間が保持され、それぞれの数ラウンド後に、ブルートフォース攻撃の迅速な処理が妨げられます。
「スロットル」とは、Webページ(機能がいくらかでもある)または5xxエラーがすぐに表示されることを意味します。 (単にログインページをもっとゆっくりと送信するのとは対照的です.. sleep()タイマーで)
おそらく、正と負の重みのハイブリッドアプローチを使用できます。私はこれを電子メールのスパムを管理するために使用し、おそらくここで学んだいくつかの教訓を共有することができます。
はじめに、成功したログインと失敗したログインの両方について、上記にリストしたすべてのデータを追跡します。次に、各変数に正の10から負の10までの「信頼水準」を割り当てます。
その後、ユーザーがログインしようとしたときに、成功したログインと失敗したログインの比率を計算し、信頼レベルで重み付けすることができます(乗算)。結果を合計し、それを使用してセッションのスロットルの程度を決定します。
browser thumbprint に注意し、ログインが成功したときにCookieを設定します。この試みでは、ログイン試行ごとに役立つ場合もあります。
企業のデスクトップ、一般消費者、および海外の読者は、それぞれの価値に異なる重み付けをする非常に異なるプロファイルを作成すると確信しています。私はあなたのプロジェクト、あなたの考え、そしてあなたが最終的に何をしているかについてもっと聞きたいと思います。
追伸ログインページで任意の計算を実行するときはいつでも、計算には常に固定長の時間(500ミリ秒)を使用します。これは、歴史的にそのようなページを悩ませてきた暗号Oracleが忍び寄るのを防ぐのに役立ちます。
P.P.Sログインページを作成するときは、Delay操作(sleep()など)でスレッドをブロックしないようにしてください。そうしないと、サーバーがすぐにDDOSになります。または、影響を受けるユーザーにHTMLまたは500エラーを返します。
私はOTPを使用しています。つまり、ログインは3つの異なるキーに基づいています。
また、1つのアプリにカウンターを追加しました。X回のログインが所定の間隔で失敗すると、次のようになります。
誤検知を防ぐために、ブロックはリモートIPに基づいている場合があります。