Spring Securityによるユーザー名列挙攻撃の防止

1. 概要

このチュートリアルでは、一般的な列挙攻撃について説明します。 具体的には、Webアプリケーションに対するユーザー名列挙攻撃を検討します。 そして、最も重要なこととして、Spring Securityを介してそれらを処理するためのオプションを検討します。

2. 列挙攻撃の説明

*列挙とは、技術的にはコレクション内のすべてのアイテムの完全で順序付けられたリストを意味します。*この定義は数学に限定されていますが、その本質は強力なハッキングツールになります。 *列挙は、悪用に利用できる攻撃ベクトルを公開することがよくあります。*このコンテキストでは、多くの場合、リソース列挙として知られています。
リソース列挙は、その名前が示すとおり、任意のホストからリソースのリストを収集する方法です。 これらのリソースは、ユーザー名、サービス、ページなど、価値のあるものであれば何でもかまいません。 これらのリソースは、ホストの潜在的な脆弱性を公開する可能性があります。
現在、これらの脆弱性を悪用する可能性のある方法はいくつかあります(調査済みまたは未調査)。

3. Webアプリケーションの一般的な列挙攻撃

  • Webアプリケーションで最もよく使用される列挙攻撃の1つは、ユーザー名列挙攻撃です。*これは基本的に、Webアプリケーションの明示的または暗黙的な機能を使用して有効なユーザー名を収集します。 攻撃者は、一般的なユーザー名の選択肢を使用してWebアプリケーションを攻撃する可能性があります。

    さて、Webアプリケーションのどのような機能がユーザー名が有効かどうかを明らかにしますか? 正直なところ、それは可能な限り多様にすることができます。 たとえば、ユーザー名が既に使用されていることをユーザーに知らせる登録ページなど、設計された機能です。
    または、これは、有効なユーザー名を使用したログイン試行に、無効なユーザー名を使用したログイン試行とは異なる時間がかかるという事実と同じくらい暗黙的である可能性があります。

4. ユーザー名列挙攻撃をエミュレートするセットアップ

Spring BootとSpring Securityを使用した簡単なユーザーWebアプリケーションを使用して、これらの攻撃ベクトルを示します。 このWebアプリケーションには、デモをサポートするための最小限の機能セットが含まれます。 link:/registration-with-spring-mvc-and-spring-security [このようなアプリケーションをセットアップする方法の詳細については、以前のチュートリアルで説明しています]。
Webアプリケーションの一般的な機能は、多くの場合、列挙攻撃の起動に使用できる情報を明らかにします。 それらを見ていきましょう。

4.1. ユーザー登録

ユーザー登録には一意のユーザー名が必要で、簡単にするためにメールアドレスがしばしば選択されます。 すでに存在するメールを選択した場合、アプリケーションは次のように通知する必要があります。
link:/uploads/Registration.jpg%201162w []
電子メールのリストが手に入りにくいという事実と相まって、これはユーザー名列挙攻撃につながり、アプリケーションで有効なユーザー名を探し出す可能性があります。

4.2. ユーザーログイン

同様に、アプリケーションにログインしようとすると、ユーザー名とパスワードを入力する必要があります。 現在、提供されたユーザー名が存在しない場合、アプリケーションはこの情報を当社に返すことがあります。
link:/uploads/Login-100x56.jpg%20100w []
これは、以前のように、ユーザー名列挙攻撃に利用するのに十分簡単です。

4.3. パスワードを再設定する

多くの場合、パスワードのリセットリンクは、ユーザーのメールに送信するために実装されます。 さて、これもユーザー名またはメールアドレスを提供する必要があります:
link:/uploads/PasswordReset-100x35.jpg%20100w []
このユーザー名または電子メールがアプリケーションに存在しない場合、アプリケーションはその旨を通知し、前に見たのと同様の脆弱性につながります。

5. ユーザー名列挙攻撃の防止

ユーザー名列挙攻撃を防ぐ方法はいくつかあります。 *それらの多くは、Webアプリケーションのユーザーメッセージなどの機能を簡単に調整することで実現できます。*
さらに、Spring Securityは時間の経過とともに十分に成熟し、これらの攻撃ベクトルの多くを処理できるようになりました。 カスタムセーフガードを作成するための、すぐに使える機能と拡張ポイントがあります。 これらの手法のいくつかを検討します。
そのような攻撃を防ぐために利用できる一般的なオプションを見てみましょう。 *これらのソリューションのすべてがWebアプリケーションのすべての部分に適しているわけではないことに注意してください。*これについては、さらに詳しく説明します。

5.1. メッセージの調整

まず、不必要に必要以上の情報を提供する可能性をすべて排除する必要があります。 これは登録では困難ですが、ログインおよびパスワードページのリセットはかなり簡単です。
たとえば、ログインページのメッセージを簡単に抽象化できます。
link:/uploads/LoginCorrected-100x51.jpg%20100w []
パスワードリセットページのメッセージに対して同様の調整を行うことができます。

5.2. CAPTCHAを含む

メッセージの調整は一部のページではうまく機能しますが、登録のようにそれを行うのが難しいページがあります。 このような場合、CAPTCHAと呼ばれる別のツールを使用できます。
さて、この時点で、列挙攻撃は非常に多くの可能性があるため、ロボット攻撃である可能性が高いことに注意する価値があります。 したがって、*人間またはロボットの存在を検出することで、攻撃を防ぐことができます*。 CAPTCHAはこれを実現する一般的な方法として機能します。
WebアプリケーションにCAPTCHAサービスを実装または統合するには、いくつかの方法があります。 これらのサービスの1つはlink:/spring-security-registration-captcha[GoogleのreCAPTCHAです。これは登録ページに簡単に統合できます]。

5.3. レート制限

CAPTCHAは目的を十分に果たしますが、正当なユーザーに待ち時間を追加し、さらに重要なことに不便を追加します。 これは、ログインのような頻繁に使用されるページにより関連しています。
*ログインなどの頻繁に使用されるページでのロボット攻撃の防止に役立つテクニックの1つに、レート制限*があります。 レート制限とは、特定のしきい値を超えたリソースの連続試行を防止することを指します。
たとえば、ログインに3回失敗すると、特定のIPからのリクエストを1日間ブロックできます。
link:/uploads/LoginBlocked-100x48.jpg%20100w []
Spring Securityはこれを特に便利にします。
最初に、_AuthenticationFailureBadCredentialsEventおよびAuthenticationSuccessEvent._のリスナーを定義します。これらのリスナーは、特定のIPからの失敗した試行回数を記録するサービスを呼び出します。 設定されたしきい値に違反すると、後続のリクエストは_UserDetailsS​​ervice_でブロックされます。
link:/spring-security-block-brute-force-authentication-attempts [このアプローチに関する詳細な議論は別のチュートリアルで利用可能です]。

5.4. ジオ制限

さらに、登録時にユーザーの国ごとに場所をキャプチャできます。 これを使用して、別の場所からのログイン試行を検証できます。 異常な場所を検出した場合、適切なアクションを実行できます。
  • キャプチャを選択的に有効にする

  • ステップアップ認証を強制する(多要素の一部として)
    認証)

  • ユーザーに場所を安全に確認するよう依頼する

  • 連続したリクエストでユーザーを一時的にブロックする

    繰り返しますが、Spring Securityは、その拡張ポイントを介して、_AuthenticationProvider_にカスタムの場所検証サービスをプラグインできるようにします。 link:/spring-security-restrict-authentication-by-geography [この特定のフレーバーは、前のチュートリアルで詳細に説明されています]。

5.5. 多要素認証

最後に、多くの場合、パスワードベースの認証が最初であり、ほとんどの場合、必要な唯一の手順であることに注意する必要があります。 しかし、*セキュリティを向上させるために、アプリケーションが多要素認証メカニズムを採用することは珍しくありません*。 これは、特にオンラインバンキングのような機密性の高いアプリケーションに当てはまります。
多要素認証に関しては、多くの要因が考えられます。
  • 知識要素:これは、PINなど、ユーザーが知っていることを指します

  • 所持要因:これは、トークンのように、ユーザーが所有するものを指します
    またはスマートフォン

  • 固有の要因:これは、ユーザーが本質的に持っているものを指します。
    指紋

    Spring Securityは、カスタム_AuthenticationProvider._をプラグインできるので、ここでも非常に便利です。GoogleAuthenticatorアプリは、追加の所持要素を実装するための一般的な選択肢です。 これにより、ユーザーはスマートフォンのアプリで一時トークンを生成し、それを任意のアプリケーションの認証に使用できます。 当然、これには、登録中または後でアプリケーションでユーザーを事前に設定する必要があります。
    link:/spring-security-two-factor-authentication-with-soft-token[SpringセキュリティアプリケーションへのGoogle認証システムの統合については、以前のチュートリアルで詳しく説明しました]。
    さらに重要なことは、*多要素認証のようなソリューションは、アプリケーションで必要な場合にのみ適しています*。 したがって、列挙攻撃を防ぐために主に使用すべきではありません。

5.6. 処理時間の遅延

ログインのようなリクエストを処理する際、多くの場合、最初に行うのはユーザー名が存在するかどうかの確認です。 ユーザー名が存在しない場合、リクエストはすぐにエラーを返します。 それどころか、有効なユーザー名を持つリクエストには、パスワードの一致やロールの検証など、さらに多くの手順が含まれます。 当然、これらの両方のケースに対応する時間は異なる場合があります。
現在、ユーザー名が有効かどうかの事実を隠すためにエラーメッセージを抽象化していますが、処理時間の大きな違いが攻撃者に悪用される可能性があります。
この問題の可能な解決策は、処理時間の違いを排除するために強制遅延を追加することです。 ただし、これは確実に発生する問題ではないため、必要な場合にのみこのソリューションを使用する必要があります。

6. まとめ

ユーザー名列挙攻撃に関して使用する多くのトリックをカバーしましたが、いつ何を使用するのかを尋ねるのは自然ですか? 明らかに、これはアプリケーションの種類とその要件に基づいているため、これに対する答えはありません。
ユーザーへのメッセージなど、いくつかの情報はできるだけ少ない情報を漏らさなければなりません。 さらに、ログインなどのリソースへの連続した失敗した試行を制限するのが賢明です。
ただし、要件が必要と判断した場合にのみ、追加の手段を使用する必要があります。 また、ユーザビリティに対する抑止力に対して合理的に比較検討する必要があります。
さらに、これらの手段の任意の組み合わせをさまざまなリソースに適用して、それらを選択的に保護できることを認識することが重要です。

7. 結論

このチュートリアルでは、列挙攻撃について、特にユーザー名列挙攻撃について説明しました。 これは、Spring Securityを使用した簡単なSpring Bootアプリケーションのレンズを通して見ました。
ユーザー名列挙攻撃の懸念に徐々に対処するために、いくつかの方法を試しました。
最後に、アプリケーションセキュリティにおけるこれらの手段の適切性について説明しました。
いつものように、例のコードは入手可能ですhttps://github.com/Baeldung/spring-security-registration[over on GitHub]。