私は最近bcryptについて考えていましたが、遅いハッシュ関数に固有の(D)DoS問題に対処する方法があるかどうかと思います。つまり、マシンがパスワードをハッシュするのに100ミリ秒かかるようにbcryptを設定した場合、サーバーが応答しなくなるのは1秒あたり10回のパスワード試行だけです。難易度を下げることはできましたが、私のために作成する速度が速ければ速いほど、攻撃者のために作成する速度が速くなります。あまりにも多くのパスワードを試す人を禁止することはできますが、最近ボットネットがいたるところにあります。
この問題に対する一般的な解決策はありますか?
おそらくクライアントに複雑であるが簡単に検証可能な何かを実行させ、パスワードをチェックする前に結果をチェックする戦略があると考えていましたが、それにはいくつかの問題があります:
私が考慮していたもう1つのことは、bcryptの結果をメモリにキャッシュすることでした。そのため、1人のユーザーに対する攻撃で問題が発生することはありません。
私は主にWebサイトのユーザー名/パスワードのログインボックスのコンテキストでこれを使用することを考えていますが、これに対処する方法は何もない場合、JavaScriptで実行できます。
編集:
どういうわけかリクエストをレート制限するという考えは役に立ちますが、それは私が考えていた種類のソリューションではありません。 (より多くのIPアドレスが必要になるため)DDoS攻撃はより高価になりますが、サーバーが攻撃者よりもはるかに多くの作業を行っているという根本的な問題は解決されません。
私が考えていることの例は、ソルト付きパスワードを使用してRainbowテーブルを悪いにする方法で、単純なブルートフォース攻撃よりも簡単です。したがって、saltを使用している場合は、より良い攻撃があるため、Rainbowテーブルについて心配する必要はありません。私が欲しいのは、ランダムなURLを打つだけでログインページを攻撃しないようにする方法です。
1つの可能性は、 クライアントパズル の使用を検討することです。基本的な考え方は、ユーザー名とパスワードのペアを受け入れて検証する前に、クライアントにかなりの量の作業を強制し、それが実行されたことを証明することです。
アプローチの概要は次のとおりです。サーバーはランダムなパズルを生成し、そのパズルをクライアントに送信します。サーバーは、パズルを解決するためにどれだけの労力が必要になるかを合理的に予測できる方法でパズルを生成します(たとえば、100ミリ秒の計算)。クライアントはパズルを解き、ソリューションをユーザーのユーザー名とパスワードとともに送信します。
Web設定では、これはおそらくJavascriptで実装されます。ログインページには、パズルとパズルの説明を解決するためのJavascriptコードが含まれます。正当なユーザーのWebブラウザーがページ上でJavascriptを実行します。これにより、パズルが解かれ、ユーザー名とパスワードと共にソリューションがフォームに含まれます。
これにより、攻撃者がサーバーにDOSを実行することが困難になります。たとえば、サーバーがユーザーのパスワードの有効性を確認するために100ミリ秒の計算を必要とし、サーバーが100ミリ秒かかるパズルを選択した場合、攻撃者は少なくともサーバーと同じだけの作業を行う必要があります。ダイヤルを回して200ミリ秒かかるパズルを選択すると、攻撃者はDOSを実行するために、2倍の作業を実行する必要があります。したがって、これはDOSを妨げませんが、攻撃をより困難にし、攻撃者がより多くのリソースを投資することを要求します-これにより、リスクがいくらか軽減される可能性があります。
これは、パズルを構築する方法の非常に単純な例です。パズルの説明は、ランダムな128ビットの数値です[〜#〜] r [〜#〜](サーバーによって選択され、クライアントに送信されます)。目標は、SHA256([〜#〜] r [〜#〜]、n)がゼロになるような数値nを見つけることです下位20ビット。クライアントはnの値をループできます(n= 0が解決策であるかどうかをテストしますn= 1が解決策であるかどうかをテストしますn= 2は解決策です...)クライアントが解決策を見つけるまで。平均して、これは約2時間がかかると予想する必要があります20 裁判。クライアントが1秒あたり約1,000万回のハッシュを実行できる場合、220 トライアルは約1/10秒(100ms)かかります。クライアントがソリューションを見つけたら、クライアントはnをサーバーに送信できます。サーバーはnがパズルの有効なソリューションであることをすばやく確認できることに注意してください(100万ハッシュではなく、ハッシュは1つだけです)。これにより、必要な非対称性が作成されます。サーバーは新しいパズルを非常に迅速に生成し、主張されたパズルソリューションを検証できますが、パズルの解決に時間がかかり、サーバーがパズルの解決にかかる時間をかなり正確に制御できます。これはパズルの構築の一例にすぎません。この問題については多くの研究が行われており、 betterconstructions があります。
あなたは特に kaPoW に興味があるかもしれません、それはウェブコンテキストのためにこの考えを実装します。
主な制限は、これが専用の攻撃に対して安全ではないということです。深刻な攻撃者は、数百台のマシン(これはそれほど高価ではありません)のボットネットを取得してDOSを実行するだけで、完全に夢中になります。クライアントパズルは、この種の攻撃を阻止することはできません。比較的低いグレードの攻撃しか阻止できません。ただし、DOSの停止は一般に非常に困難です。
二次的な制限は、あなたのウェブサイトにアクセスするかもしれないクライアントの計算能力の多様性に関係しています。ハイエンドのデスクトップが100ミリ秒で解決できるパズルでは、モバイルデバイスが1000ミリ秒で解決する場合があります(ここでは数値を計算しています)。 Webサイトにアクセスする可能性が最も低い、最も消費電力の少ないデバイスでパズルを比較的簡単に解決できるパラメーターを選択すると、ハイエンドデスクトップに対するセキュリティが低下することがあります。また、Cプログラム(攻撃者が実行)がJavascript(正当なユーザーが実行)よりもはるかに速くパズルを解くことができる可能性が高く、攻撃者がパズルを解く速度と、パズルを解く速度のギャップがさらに悪化する可能性があります。最も遅い正当なクライアントがどれだけ速くそれらを解決できるか。このギャップはセキュリティを低下させます。
第3の制限は、クライアントのパズルでは、クライアントがログインするためにJavascriptを使用する必要があることです。ただし、これは許容される場合があります。
このアイデアの変形は、サーバーがそれ自体を監視し、負荷が高いかどうかを確認することです。通常の状況では、パズルをスキップします。ただし、サーバーがDOS攻撃を受けていると思われる場合は、パズルソリューションを使用するためにログイン試行を要求し始めます。これにより、クライアントパズルアプローチのいくつかの欠点が緩和されますが、完全とはほど遠く、深刻なDOS攻撃に耐えることはできません。
興味がある場合に備えて、この潜在的な解決策について説明しますが、ほとんどのサイトにはあまりお勧めしません。ほとんどのサイトでは、DOSのリスクは比較的低く、発生した場合はその時点で対処できます。そのため、私は、これらの種類の防御策を実装することは、おそらくあなたの時間やエネルギーの価値がないと思います。余計な時間とエネルギーを費やすことができれば、新しい機能の構築やサイトの改善に費やすほうがよいでしょう。
1分あたりの推測の数を減らすことをお勧めしますが、それをコードにsleep
として実装すると、貴重なリソースが消費され、サービス拒否につながります。
代わりに、サーバーではなくクライアントを待機させます。そのため、試行が行われた時間をログに記録し、その時間にX
秒を追加します。その時間が経過するまで、そのユーザー/ IPからの認証を試行しないでください。 (編集、追加:)つまり、認証の試みを受け取った場合、パスワードをチェックすることなく、エラーメッセージで拒否します。
ログインページに対応するjavascriptを配置して、タイムアウトの期限が切れるまで(および安全マージンを追加するまで)ユーザーが新しいログイン試行を送信しないようにする必要があります。これにより、ユーザーは不要なエラーメッセージを確認したり、混乱したりすることがなくなります。
試行ごとにタイムアウトを増やすこともお勧めします。これにより、ブルートフォース攻撃を事実上不可能にしながら、「通常の」ユーザーの不便を回避できます。
考慮することができる別のアプローチは、CAPTCHAを使用してこの種のDOS攻撃をより困難にすることです。基本的な考え方は、ユーザーがログインするときにCAPTCHAを解くように要求し、パスワードを検証する前にCAPTCHAに正しい解決策を提示するように要求することです。
これはユーザーにとって不親切なので、これを検討したい場合は、別の方法をお勧めします。サーバーに独自の負荷を監視させ、攻撃を受けていることを検出できるようにします。 (たとえば、bcrypt-hashingパスワードに費やしているCPU時間を測定するか、サーバーの負荷を測定します。)通常の状態では、特別なことは何もしません。ユーザーは通常どおり、ユーザー名とパスワードを提示するだけです、CAPTCHAはどこにもありません。
攻撃を受けている可能性があることを検出したら、自己保護モードに入ります。このモードでは、サーバーはログインページでCAPTCHAを送信し、ユーザーにユーザー名の入力、パスワードの入力、CAPTCHAのソリューションの入力を求めます。ユーザーが[送信]をクリックすると、サーバーは最初にCAPTCHAに対するソリューションを検証してから、bcryptを使用してユーザーのパスワードを検証する必要があります。ユーザーがキャプチャを適切に解決しなかった場合は、パスワードの確認も行わないでください。
これにより、攻撃者は1秒あたり10個の無効なユーザー名/パスワードのペアを送信できないため、DOS攻撃に対する基準が引き上げられます。攻撃者は、1秒あたり10個のCAPTCHAも解決してサーバーをDOS化する必要があります。その結果、ささいなDOS攻撃は成功しなくなりました。また、これはDOS耐性を提供し、ほとんどの状況でユーザーがキャプチャを表示する必要がないことを保証します。ユーザーは、サーバーが攻撃を受けているときにのみキャプチャを解決する必要があります。
もちろん、必要に応じて、このスキームをIPアドレスおよびユーザー名によるレート制限と組み合わせることができます。
とはいえ、このスキームのセキュリティは完全とはほど遠いものです。 CAPTCHAを有料で解決するプロセスを自動化するために存在する攻撃者が使用する地下市場があります。これらのサービスは、CAPTCHAを送信してソリューションを取得するために顧客が使用できるAPIを提供します。 現在のレート は、CAPTCHAが1,000解決されるごとに数ドルかかるようなものです。これに基づいて、これらのCAPTCHA解決サービスを使用して、このスキームに対するDOS攻撃を成功させるためにかかる費用を計算できます。攻撃者は、サーバーを停止するために1日あたり864,000 CAPTCHA(1秒あたり10)を解決する必要があります。これは、既存の市場を使用した場合、1日あたり数千ドルのダウンタイムが発生します。これは、DOS攻撃を成功させるためのコストの上限です。ただし、サーバーにDOS攻撃を仕掛ける他のはるかに経済的な方法がほぼ確実にあるため、サーバーをDOS化するコストはほぼ確実に過大評価されます。
とにかく、CAPTCHAの使用に基づいてこの潜在的なソリューションを共有しますが、ほとんどのサイトにはあまりお勧めしません。ほとんどのサイトでは、DOSのリスクは比較的低く、発生した場合はその時点で対処できます。そのため、私は、これらの種類の防御策を実装するのに、時間や労力を費やす価値はおそらくないと思います。余計な時間とエネルギーを費やすことができれば、新しい機能の構築やサイトの改善に費やすほうがよいでしょう。
現在、DDOSはサーバーを停止する最も簡単で最も安価な方法です。私は 1日あたり100ドル の範囲でDDOS攻撃のコストの見積もりを見ましたが、より大きく、よりリソースのあるターゲットを倒すには 大幅に多く のコストがかかる可能性があります。
DOS攻撃からサーバーを保護することは 簡単ではありません ;それの経済学はあなたのために働いていません。おそらく、あなたができる最善のことの1つは、サイトに大量の余剰容量を持たせ、トラフィックの増加に応じて規模を拡大できるようにすることです(おそらく、オンデマンドのVMとネットワーク容量を備えたクラウドサービスを使用します)。このアプローチの利点は、DOS攻撃を受けたことがない場合でも有益であることです。これは、Slashdottedを取得した場合など、正当なユーザーの洪水に圧倒されないようにするのに役立ちます。
あなたができることは、ログインが失敗するたびにリクエストを指数関数的にスリープさせることです。
最初のログインで1秒間ホールドします。秒は2秒失敗しました。 3番目は4秒など失敗しました。または、サーバーが処理できる内容に応じて、これより長くまたは短くなります。パスワードを打ち間違えた通常のユーザーに害を与えることはありませんが、ブルートフォースを試みる人は、ほんの数回の失敗で非常に長い時間待機することになります。
私のDoSに対する一般的な見方は次のとおりです。既存のシステムはすべてDoSに対して根本的に脆弱です。それは単に学位の問題です。 DoSのリスクが高い有名なサイトがある場合は、これらのベクターについて心配する価値があるかもしれません。普通の日常のサイトを運営しているだけなら、気にしないでしょう。ほとんどのセクターでは、DOS攻撃はまれであるため、防御に時間とエネルギーを費やす価値はないでしょう。 (もちろん例外はありますが、ここではほとんどのサイトについて話しています。)
DoS攻撃の優れている点は、DoS攻撃が発生しても、すぐに検出できることです。
Edit(2/25):私が明確にした制限にもかかわらず、計算DOS攻撃に対してできることを本当にしたいようです。それを考慮して、計算DOS攻撃をより困難にするいくつかの方法については、私の otheranswers を参照してください。それらは完璧とはほど遠いものであり、個人的には私は最終的な推奨事項に固執しています(つまり、これらの防御策を実装することは、おそらくあなたの時間の最善の使用法ではありません)。
基本的に、リスク評価を行うための最初のステップ:
上記の回答に応じて、対策は異なります-たとえば:
心に留めておくべきこと:
帯域幅とIPが制限されていない攻撃者に直面した場合でも、最善の防御は維持されません...
私の簡単な推奨事項、および遅いパスワードハッシュに対するDoS攻撃を緩和するために私が行ったことは、主要な検証方法としてパスワード強度の計算スコアを使用することです。
したがって、ユーザーログインの例では、ユーザーレコードを電子メールで取得します。次に、最初に強度スコアがプレーンテキストのパスワードと一致するかどうかを確認します(これは明らかに高速で、機能は2つだけです)。また、パスワードのハッシュ関数はスコアの一致でのみ開始します。それ以外の場合は、失敗した要求で保釈します。
また、データベースでパスワードの強度を公開しないようにするために、実際のパスワード強度スコアを隠すための、ある種の基本的な一方向計算アルゴリズムを見つけることができます。