| Title | pgAdmin ProjectのpgAdmin 4における過度な認証試行の不適切な制限に関する脆弱性 |
|---|---|
| Summary | pgAdmin 4における過剰な認証試行の不適切な制限(CWE-307)に関する問題です。pgAdminはMAX_LOGIN_ATTEMPTSをカスタムの/authenticate/loginビュー内でのみ強制しています。Flask-Securityのデフォルトの/loginビューは security.init_app()により自動的に登録され、すべてのサーバーでアクセス可能ですが、User.lockedフィールドを参照していませんでした。pgAdminのUserモデルはFlask-SecurityのUserMixin.is_locked()(常に「ロックされていない」と返します)およびFlask-Loginのis_active(lockedではなくactiveカラムのみをチェックします)に依存していました。したがって、/authenticate/login経由でアカウントロックアウトを引き起こした攻撃者は、/loginに有効な資格情報を再送信することでセッションを取得でき、INTERNAL認証ソースを使用するアカウントに対するブルートフォース保護制御を回避可能でした。同様の回避により、/login経由のログイン試行はレート制限されないため、攻撃者はMAX_LOGIN_ATTEMPTSに関係なくINTERNALアカウントに対して無制限のオンラインパスワード推測攻撃を実行できます。修正では、すべての認証経路でlockedカラムを強制するためにUser.is_activeおよびUser.is_locked()をオーバーライドしました。LDAP、OAuth2、Kerberos、およびWebserverユーザーはローカルパスワードを持たず、lockedチェック前にFlask-SecurityのLoginForm.validateで拒否されるため、このバイパスの対象外です。ロックアウト自体も内部限定であり、/authenticate/loginビューはauth_source=INTERNALでフィルタリングされます。この問題はpgAdmin 4の9.15以前のバージョンに影響を及ぼします。 |
| Possible impacts | 当該ソフトウェアが扱う情報の一部が外部に漏れる可能性があります。 また、当該ソフトウェアが扱う情報の一部が書き換えられる可能性があります。 さらに、当該ソフトウェアは停止しません。 そして、この脆弱性を悪用した攻撃の影響は、他のソフトウェアには及びません。 |
| Solution | 正式な対策が公開されています。ベンダ情報を参照して適切な対策を実施してください。 |
| Publication Date | May 11, 2026, midnight |
| Registration Date | May 28, 2026, 2:38 p.m. |
| Last Update | May 28, 2026, 2:38 p.m. |
| CVSS3.0 : 警告 | |
| Score | 6.5 |
|---|---|
| Vector | CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N |
| pgAdmin Project |
| pgAdmin 4 9.15 未満 |
| No | Changed Details | Date of change |
|---|---|---|
| 1 | [2026年05月28日] 掲載 |
May 28, 2026, 2:38 p.m. |
| Summary | Improper restriction of excessive authentication attempts (CWE-307) in pgAdmin 4. pgAdmin enforces MAX_LOGIN_ATTEMPTS only inside its custom /authenticate/login view. Flask-Security's default /login view, which is registered automatically by security.init_app() and is reachable on every server, never consulted the User.locked field: pgAdmin's User model relied on Flask-Security's UserMixin.is_locked() (which always returns 'not locked') and Flask-Login's is_active (which only checks the active column, not locked). An attacker who triggered an account lockout via /authenticate/login could therefore obtain a session by re-submitting valid credentials directly to /login, defeating the brute-force-protection control for accounts using the INTERNAL authentication source. The same bypass also means that login attempts via /login are never rate-limited, so an attacker can perform an unbounded online password-guessing attack against INTERNAL accounts regardless of MAX_LOGIN_ATTEMPTS. Fix overrides User.is_active and User.is_locked() so the locked column is enforced on every authentication path. LDAP, OAuth2, Kerberos, and Webserver users are not reachable by this bypass because they have no local password and are rejected by Flask-Security's LoginForm.validate before the locked check; the lockout itself is also internal-only (the /authenticate/login view filters by auth_source=INTERNAL). This issue affects pgAdmin 4: before 9.15. |
|---|---|
| Publication Date | May 12, 2026, 1:17 a.m. |
| Registration Date | May 12, 2026, 4:14 a.m. |
| Last Update | May 14, 2026, 12:34 a.m. |