Username Enumeration Prevention
パスワードリセットフォームのエラーメッセージを抑制し、ユーザープロファイルルートの403 Access Denied応答を404 Not Foundに変換することで、ユーザー名列挙攻撃を軽減します。
username_enumeration_prevention
インストール
composer require 'drupal/username_enumeration_prevention:8.x-1.4'
composer require 'drupal/username_enumeration_prevention:8.x-1.3'
概要
Username Enumeration Preventionは、Drupalサイトをユーザー名列挙攻撃から保護するセキュリティ重視のモジュールです。ユーザー名列挙とは、悪意のある攻撃者がWebアプリケーション上の有効なユーザー名を特定するために使用する手法であり、その情報はクレデンシャルスタッフィング、ブルートフォース攻撃、ソーシャルエンジニアリングなどの攻撃に利用される可能性があります。
このモジュールは主に2つのメカニズムで動作します。まず、パスワードリセットフォームを変更し、ユーザー名やメールアドレスがシステムに存在するかどうかを示すメッセージが表示されないようにします。「%nameはブロックされているか、まだ有効化されていません」や「%nameはユーザー名またはメールアドレスとして認識されません」などのメッセージは、管理者向けにはログに記録されつつ、エンドユーザーには表示されません。次に、すべてのユーザー関連ルートでHTTP 403 Access Denied応答を404 Not Found応答に変換するイベントサブスクライバーを実装し、攻撃者が存在しないユーザーとアクセスできないユーザーを区別できないようにします。
また、匿名ユーザーが「ユーザープロファイルへのアクセス」権限を持っている場合、このモジュールの保護をバイパスする可能性があるため、ランタイムステータスレポートで警告を表示します。
Features
- 有効なユーザー名やメールアドレスを漏洩する可能性のあるパスワードリセットフォームのエラーメッセージを抑制
- ユーザープロファイルおよびユーザー関連ルートで403 Access Denied HTTP応答を404 Not Foundに変換
- ブロックされたユーザーのパスワードリセット試行を、攻撃者に情報を公開することなく管理者レビュー用にログに記録
- 列挙を助ける可能性のあるフラッド関連のエラーメッセージを抑制しつつ、フラッド保護機能を維持
- 匿名ユーザーがユーザープロファイルにアクセスできる場合にランタイム要件チェックで警告を表示
- Drupal 9.5、10、11をサポート
Use Cases
パスワードリセットによる列挙の防止
攻撃者がさまざまなユーザー名でパスワードリセットフォームを送信して有効なユーザー名を列挙しようとする場合、通常は有効なユーザー名と無効なユーザー名で異なるメッセージが表示されます。このモジュールを使用すると、ユーザー名が存在するか、ブロックされているか、無効であるかに関係なく、すべての送信で同じ応答が返されます。これにより、攻撃者が有効なユーザーアカウントのリストを作成することを防ぎます。
ユーザープロファイルURLの保護
このモジュールがない場合、攻撃者は /user/1、/user/2 などにアクセスすることで有効なユーザーIDを列挙できます。存在するユーザーは403 Access Deniedを返し、存在しないユーザーは404を返すためです。このモジュールを使用すると、どちらのシナリオでも404が返されるため、両者を区別することが不可能になります。
セキュリティ標準への準拠
ユーザー列挙の防止を推奨するOWASPガイドラインなどのセキュリティ標準に従う組織は、セキュリティ強化戦略の一環としてこのモジュールを実装できます。
クレデンシャルスタッフィングの準備への対策
攻撃者はクレデンシャルスタッフィング攻撃を開始する前に、有効なユーザー名を列挙することがよくあります。ユーザー名の列挙を防ぐことで、このモジュールは攻撃者が既知の有効なアカウントに対する標的型攻撃を準備することをより困難にします。
Tips
- Nodeやコメントの「投稿者」情報を通じてユーザー名を公開する可能性のあるViewsやコンテンツ表示設定を確認してください
- ログインフォームのブラウザオートコンプリートを無効にするためにSecurity Kitモジュールの使用を検討してください
- Drupalセキュリティチームはユーザー名列挙を重大な脆弱性とは見なしていませんが、高セキュリティサイトでは懸念事項となる可能性があることを覚えておいてください
- モジュールはブロックされたユーザーのパスワードリセット試行をログに記録します - 不審なアクティビティがないか定期的にログを確認してください
- 匿名セッションから存在しないユーザーやブロックされたユーザーのパスワードリセットを試みて、モジュールの有効性をテストしてください
Technical Details
Hooks 2
hook_form_user_pass_alter
パスワードリセットフォームを変更し、ユーザー名列挙エラーメッセージを抑制するカスタムバリデーションを追加します
hook_requirements
匿名ユーザーが「ユーザープロファイルへのアクセス」権限を持っているかどうかをチェックするランタイム要件を実装します。この権限があるとモジュールの保護がバイパスされます
Troubleshooting 4
/admin/reports/status のステータスレポートを確認してください。匿名ユーザーのプロファイルアクセスについて警告が表示されている場合は、/admin/people/permissions で匿名ロールから「ユーザープロファイルへのアクセス」権限を削除してください。
このモジュールは有効なユーザーへのパスワードリセットメールの送信を妨げません。メールが送信されない場合は、メールシステムの設定、スパムフィルター、およびユーザーアカウントが存在しアクティブであることを確認してください。モジュールはエラーメッセージのみを抑制し、実際の機能には影響しません。
これは期待される動作です。モジュールは意図的にフラッド制御メッセージを抑制します。これらのメッセージがユーザー名が有効であることを示す可能性があるためです(攻撃者はレート制限を受けた場合、有効なユーザーにヒットしたことがわかります)。フラッド保護はサーバー側で引き続き機能します。
サイトで匿名ユーザーがプロファイルを表示する必要がある場合、これによりこのモジュールでは完全に軽減できないユーザー名列挙の脆弱性が生じることを理解してください。この権限がユースケースに本当に必要かどうかを検討してください。
Security Notes 5
- 「ユーザープロファイルへのアクセス」権限を持つユーザーは、/user/UID URLにアクセスすることでまだユーザー名を列挙できます - モジュールは403を404に変換することしかできず、アクセスを完全に防ぐことはできません
- Nodeやコメントの「投稿者」情報はユーザー名を公開する可能性があります - 表示設定の調整やformat_usernameフックの使用を検討してください
- ユーザー情報を表示するViewsはユーザー名を公開する可能性があります - Views設定を監査してください
- ブラウザのオートコンプリートがユーザー名を明らかにする可能性があります - Security Kitモジュールを使用してこの機能を無効にしてください
- このモジュールはユーザー名列挙の1つのベクトルに対処します。包括的なセキュリティ戦略では、すべての潜在的な露出ポイントに対処する必要があります