CVE-2021-38155
Description
OpenStack Keystone 10.x through 16.x before 16.0.2, 17.x before 17.0.1, 18.x before 18.0.1, and 19.x before 19.0.1 allows information disclosure during account locking (related to PCI DSS features). By guessing the name of an account and failing to authenticate multiple times, any unauthenticated actor could both confirm the account exists and obtain that account's corresponding UUID, which might be leveraged for other unrelated attacks. All deployments enabling security_compliance.lockout_failure_attempts are affected.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
OpenStack Keystone account locking leaks user existence and UUID to unauthenticated attackers via error messages.
Vulnerability
OpenStack Keystone versions 10.x through 16.x before 16.0.2, 17.x before 17.0.1, 18.x before 18.0.1, and 19.x before 19.0.1 contain an information disclosure vulnerability in the account locking feature. When security_compliance.lockout_failure_attempts is enabled, the server returns an AccountLocked exception that includes the user's UUID in the error message. This allows any unauthenticated actor to confirm the existence of an account and obtain its corresponding UUID by repeatedly attempting authentication with a guessed username and an incorrect password. The feature is part of PCI DSS compliance (requirements 8.1.6 and 8.1.7) [1][2][3].
Exploitation
An attacker can exploit this vulnerability by sending multiple authentication requests to the Keystone API using a guessed username and an incorrect password. After the configured number of failed attempts (e.g., 2 attempts when lockout_failure_attempts = 2), the server responds with an AccountLocked error message that contains the user's UUID in the format: "The account is locked for user: ". Before the lockout threshold, the server returns a generic "The request you have made requires authentication." message, which does not reveal whether the account exists. The attacker can also trigger lockout by attempting to change the user's password via /v3/users/<user_id>/password with an incorrect original password, but this requires knowing the user's UUID first. No authentication or prior access is needed for the main attack vector [3].
Impact
Successful exploitation allows an unauthenticated attacker to confirm the existence of user accounts and obtain their UUIDs. This information leakage can be leveraged in further attacks, such as targeted password guessing, social engineering, or other unrelated attacks that rely on knowing valid account identifiers. The vulnerability does not directly allow account takeover or privilege escalation, but it weakens the security of the identity system by exposing internal identifiers [1][2].
Mitigation
The vulnerability is fixed in Keystone versions 16.0.2, 17.0.1, 18.0.1, and 19.0.1. The fix changes the exception handling to return a generic Unauthorized error message instead of AccountLocked, preventing the disclosure of the user UUID. Users should upgrade to the patched versions as soon as possible. The fix is included in commit 8ab4eb27be4c13c9bab2b3ea700f00a190521bf8 [4]. As a workaround, operators can disable the security_compliance.lockout_failure_attempts option, but this may violate PCI DSS requirements for account locking [2][3].
- NVD - CVE-2021-38155
- security - [OSSA-2021-003] Keystone: Account name and UUID oracles in account locking (CVE-2021-38155)
- Bug #1688137 “[OSSA-2021-003] Account name and UUID oracles in a...” : Bugs : OpenStack Identity (keystone)
- Hide AccountLocked exception from end users · openstack/keystone@8ab4eb2
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
keystonePyPI | >= 10.0, < 16.0.2 | 16.0.2 |
keystonePyPI | >= 17.0, < 17.0.1 | 17.0.1 |
keystonePyPI | >= 18.0, < 18.0.1 | 18.0.1 |
keystonePyPI | >= 19.0, < 19.0.1 | 19.0.1 |
Affected products
82- OpenStack/Keystonedescription
- ghsa-coords81 versionspkg:pypi/keystonepkg:rpm/suse/ardana-barbican&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/documentation-hpe-helion-openstack-installation&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/documentation-hpe-helion-openstack-operations&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/documentation-hpe-helion-openstack-opsconsole&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/documentation-hpe-helion-openstack-planning&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/documentation-hpe-helion-openstack-security&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/documentation-hpe-helion-openstack-user&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/documentation-suse-openstack-cloud-deployment&distro=SUSE%20OpenStack%20Cloud%20Crowbar%208pkg:rpm/suse/documentation-suse-openstack-cloud-installation&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/documentation-suse-openstack-cloud-operations&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/documentation-suse-openstack-cloud-opsconsole&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/documentation-suse-openstack-cloud-planning&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/documentation-suse-openstack-cloud-security&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/documentation-suse-openstack-cloud-supplement&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/documentation-suse-openstack-cloud-supplement&distro=SUSE%20OpenStack%20Cloud%20Crowbar%208pkg:rpm/suse/documentation-suse-openstack-cloud-upstream-admin&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/documentation-suse-openstack-cloud-upstream-admin&distro=SUSE%20OpenStack%20Cloud%20Crowbar%208pkg:rpm/suse/documentation-suse-openstack-cloud-upstream-user&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/documentation-suse-openstack-cloud-upstream-user&distro=SUSE%20OpenStack%20Cloud%20Crowbar%208pkg:rpm/suse/documentation-suse-openstack-cloud-user&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/grafana&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/grafana&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/kibana&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/kibana&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/kibana&distro=SUSE%20OpenStack%20Cloud%20Crowbar%208pkg:rpm/suse/openstack-barbican&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/openstack-barbican&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/openstack-cinder&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/openstack-cinder&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/openstack-heat-gbp&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/openstack-heat-gbp&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/openstack-horizon-plugin-gbp-ui&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/openstack-horizon-plugin-gbp-ui&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/openstack-ironic&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/openstack-ironic&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/openstack-keystone&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/openstack-keystone&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/openstack-keystone&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/openstack-keystone&distro=SUSE%20OpenStack%20Cloud%20Crowbar%208pkg:rpm/suse/openstack-keystone&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/openstack-keystone-doc&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/openstack-keystone-doc&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/openstack-keystone-doc&distro=SUSE%20OpenStack%20Cloud%20Crowbar%208pkg:rpm/suse/openstack-monasca-notification&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/openstack-monasca-notification&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/openstack-monasca-notification&distro=SUSE%20OpenStack%20Cloud%20Crowbar%208pkg:rpm/suse/openstack-neutron&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/openstack-neutron&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/openstack-neutron-gbp&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/openstack-neutron-gbp&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/python-lxml&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/python-lxml&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/python-Pillow&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/python-Pillow&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/python-XStatic-jquery-ui&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/python-XStatic-jquery-ui&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/release-notes-suse-openstack-cloud&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/release-notes-suse-openstack-cloud&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/rubygem-sinatra&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209pkg:rpm/suse/venv-openstack-barbican&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-cinder&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-designate&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-glance&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-heat&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-horizon&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-ironic&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-keystone&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/venv-openstack-keystone&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/venv-openstack-keystone&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-magnum&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-manila&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-monasca-ceilometer&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-monasca&distro=HPE%20Helion%20OpenStack%208pkg:rpm/suse/venv-openstack-monasca&distro=SUSE%20OpenStack%20Cloud%208pkg:rpm/suse/venv-openstack-monasca&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-neutron&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-nova&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-octavia&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-sahara&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/venv-openstack-swift&distro=SUSE%20OpenStack%20Cloud%209
>= 10.0, < 16.0.2+ 80 more
- (no CPE)range: >= 10.0, < 16.0.2
- (no CPE)range: < 9.0+git.1644879908.8a641c1-3.13.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 8.20211112-1.38.1
- (no CPE)range: < 6.7.4-3.26.1
- (no CPE)range: < 6.7.4-3.26.1
- (no CPE)range: < 4.6.6-3.12.1
- (no CPE)range: < 4.6.6-3.12.1
- (no CPE)range: < 4.6.6-3.12.1
- (no CPE)range: < 7.0.1~dev24-3.14.1
- (no CPE)range: < 7.0.1~dev24-3.14.1
- (no CPE)range: < 13.0.10~dev24-3.34.2
- (no CPE)range: < 13.0.10~dev24-3.34.2
- (no CPE)range: < 14.0.1~dev4-3.9.1
- (no CPE)range: < 14.0.1~dev4-3.9.1
- (no CPE)range: < 14.0.1~dev3-3.9.1
- (no CPE)range: < 14.0.1~dev3-3.9.1
- (no CPE)range: < 11.1.5~dev18-3.28.2
- (no CPE)range: < 11.1.5~dev18-3.28.2
- (no CPE)range: < 12.0.4~dev11-5.36.1
- (no CPE)range: < 12.0.4~dev11-5.36.1
- (no CPE)range: < 14.2.1~dev9-3.28.2
- (no CPE)range: < 12.0.4~dev11-5.36.1
- (no CPE)range: < 14.2.1~dev9-3.28.2
- (no CPE)range: < 12.0.4~dev11-5.36.1
- (no CPE)range: < 12.0.4~dev11-5.36.1
- (no CPE)range: < 12.0.4~dev11-5.36.1
- (no CPE)range: < 1.10.2~dev4-3.9.1
- (no CPE)range: < 1.10.2~dev4-3.9.1
- (no CPE)range: < 1.10.2~dev4-3.9.1
- (no CPE)range: < 13.0.8~dev206-3.40.1
- (no CPE)range: < 13.0.8~dev206-3.40.1
- (no CPE)range: < 14.0.1~dev33-3.31.1
- (no CPE)range: < 14.0.1~dev33-3.31.1
- (no CPE)range: < 4.2.4-3.3.1
- (no CPE)range: < 4.2.4-3.3.1
- (no CPE)range: < 5.2.0-3.17.1
- (no CPE)range: < 5.2.0-3.17.1
- (no CPE)range: < 1.13.0.1-4.3.1
- (no CPE)range: < 1.13.0.1-4.3.1
- (no CPE)range: < 9.20220413-3.30.1
- (no CPE)range: < 9.20220413-3.30.1
- (no CPE)range: < 1.4.6-4.3.1
- (no CPE)range: < 7.0.1~dev24-3.35.2
- (no CPE)range: < 13.0.10~dev24-3.38.1
- (no CPE)range: < 7.0.2~dev2-3.35.1
- (no CPE)range: < 17.0.1~dev30-3.33.1
- (no CPE)range: < 11.0.4~dev4-3.35.1
- (no CPE)range: < 14.1.1~dev11-4.39.1
- (no CPE)range: < 11.1.5~dev18-4.33.1
- (no CPE)range: < 12.0.4~dev11-11.45.1
- (no CPE)range: < 12.0.4~dev11-11.45.1
- (no CPE)range: < 14.2.1~dev9-3.36.1
- (no CPE)range: < 7.2.1~dev1-4.35.1
- (no CPE)range: < 7.4.2~dev60-3.41.1
- (no CPE)range: < 1.8.2~dev3-3.35.1
- (no CPE)range: < 2.2.2~dev1-11.45.1
- (no CPE)range: < 2.2.2~dev1-11.45.1
- (no CPE)range: < 2.7.1~dev10-3.37.1
- (no CPE)range: < 13.0.8~dev206-6.39.1
- (no CPE)range: < 18.3.1~dev91-3.39.1
- (no CPE)range: < 3.2.3~dev7-4.35.1
- (no CPE)range: < 9.0.2~dev15-3.35.1
- (no CPE)range: < 2.19.2~dev48-2.30.1
Patches
31b573ae7d1c2Hide AccountLocked exception from end users
4 files changed · +16 −6
keystone/notifications.py+2 −0 modified@@ -580,6 +580,8 @@ def wrapper(wrapped_self, user_id, *args, **kwargs): taxonomy.OUTCOME_FAILURE, target, self.event_type, reason=audit_reason) + if isinstance(ex, exception.AccountLocked): + raise exception.Unauthorized raise except Exception: # For authentication failure send a CADF event as well
keystone/tests/unit/common/test_notifications.py+1 −1 modified@@ -802,7 +802,7 @@ def test_locked_out_user_sends_notification(self): password = uuid.uuid4().hex new_password = uuid.uuid4().hex expected_responses = [AssertionError, AssertionError, AssertionError, - exception.AccountLocked] + exception.Unauthorized] user_ref = unit.new_user_ref(domain_id=self.domain_id, password=password) user_ref = PROVIDERS.identity_api.create_user(user_ref)
keystone/tests/unit/identity/test_backend_sql.py+5 −5 modified@@ -576,7 +576,7 @@ def test_locking_out_user_after_max_failed_attempts(self): ) # test locking out user after max failed attempts self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -605,7 +605,7 @@ def test_set_enabled_unlocks_user(self): with self.make_request(): # lockout user self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -624,7 +624,7 @@ def test_lockout_duration(self): with self.make_request(): # lockout user self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -650,7 +650,7 @@ def test_lockout_duration_failed_auth_cnt_resets(self): with self.make_request(): # lockout user self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -660,7 +660,7 @@ def test_lockout_duration_failed_auth_cnt_resets(self): # repeat failed auth the max times self._fail_auth_repeatedly(self.user['id']) # test user account is locked - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex)
releasenotes/notes/bug-1688137-e4203c9a728690a7.yaml+8 −0 added@@ -0,0 +1,8 @@ +--- +fixes: + - | + [`bug 1688137 <https://bugs.launchpad.net/keystone/+bug/1688137>`_] + Fixed the AccountLocked exception being shown to the end user since + it provides some information that could be exploited by a + malicious user. The end user will now see Unauthorized instead of + AccountLocked, preventing user info oracle exploitation.
ac2631ae3344Hide AccountLocked exception from end users
4 files changed · +16 −6
keystone/notifications.py+2 −0 modified@@ -580,6 +580,8 @@ def wrapper(wrapped_self, user_id, *args, **kwargs): taxonomy.OUTCOME_FAILURE, target, self.event_type, reason=audit_reason) + if isinstance(ex, exception.AccountLocked): + raise exception.Unauthorized raise except Exception: # For authentication failure send a CADF event as well
keystone/tests/unit/common/test_notifications.py+1 −1 modified@@ -802,7 +802,7 @@ def test_locked_out_user_sends_notification(self): password = uuid.uuid4().hex new_password = uuid.uuid4().hex expected_responses = [AssertionError, AssertionError, AssertionError, - exception.AccountLocked] + exception.Unauthorized] user_ref = unit.new_user_ref(domain_id=self.domain_id, password=password) user_ref = PROVIDERS.identity_api.create_user(user_ref)
keystone/tests/unit/identity/test_backend_sql.py+5 −5 modified@@ -613,7 +613,7 @@ def test_locking_out_user_after_max_failed_attempts(self): ) # test locking out user after max failed attempts self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -642,7 +642,7 @@ def test_set_enabled_unlocks_user(self): with self.make_request(): # lockout user self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -661,7 +661,7 @@ def test_lockout_duration(self): with self.make_request(): # lockout user self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -687,7 +687,7 @@ def test_lockout_duration_failed_auth_cnt_resets(self): with self.make_request(): # lockout user self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -697,7 +697,7 @@ def test_lockout_duration_failed_auth_cnt_resets(self): # repeat failed auth the max times self._fail_auth_repeatedly(self.user['id']) # test user account is locked - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex)
releasenotes/notes/bug-1688137-e4203c9a728690a7.yaml+8 −0 added@@ -0,0 +1,8 @@ +--- +fixes: + - | + [`bug 1688137 <https://bugs.launchpad.net/keystone/+bug/1688137>`_] + Fixed the AccountLocked exception being shown to the end user since + it provides some information that could be exploited by a + malicious user. The end user will now see Unauthorized instead of + AccountLocked, preventing user info oracle exploitation.
8ab4eb27be4cHide AccountLocked exception from end users
4 files changed · +16 −6
keystone/notifications.py+2 −0 modified@@ -580,6 +580,8 @@ def wrapper(wrapped_self, user_id, *args, **kwargs): taxonomy.OUTCOME_FAILURE, target, self.event_type, reason=audit_reason) + if isinstance(ex, exception.AccountLocked): + raise exception.Unauthorized raise except Exception: # For authentication failure send a CADF event as well
keystone/tests/unit/common/test_notifications.py+1 −1 modified@@ -802,7 +802,7 @@ def test_locked_out_user_sends_notification(self): password = uuid.uuid4().hex new_password = uuid.uuid4().hex expected_responses = [AssertionError, AssertionError, AssertionError, - exception.AccountLocked] + exception.Unauthorized] user_ref = unit.new_user_ref(domain_id=self.domain_id, password=password) user_ref = PROVIDERS.identity_api.create_user(user_ref)
keystone/tests/unit/identity/test_backend_sql.py+5 −5 modified@@ -576,7 +576,7 @@ def test_locking_out_user_after_max_failed_attempts(self): ) # test locking out user after max failed attempts self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -605,7 +605,7 @@ def test_set_enabled_unlocks_user(self): with self.make_request(): # lockout user self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -624,7 +624,7 @@ def test_lockout_duration(self): with self.make_request(): # lockout user self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -650,7 +650,7 @@ def test_lockout_duration_failed_auth_cnt_resets(self): with self.make_request(): # lockout user self._fail_auth_repeatedly(self.user['id']) - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex) @@ -660,7 +660,7 @@ def test_lockout_duration_failed_auth_cnt_resets(self): # repeat failed auth the max times self._fail_auth_repeatedly(self.user['id']) # test user account is locked - self.assertRaises(exception.AccountLocked, + self.assertRaises(exception.Unauthorized, PROVIDERS.identity_api.authenticate, user_id=self.user['id'], password=uuid.uuid4().hex)
releasenotes/notes/bug-1688137-e4203c9a728690a7.yaml+8 −0 added@@ -0,0 +1,8 @@ +--- +fixes: + - | + [`bug 1688137 <https://bugs.launchpad.net/keystone/+bug/1688137>`_] + Fixed the AccountLocked exception being shown to the end user since + it provides some information that could be exploited by a + malicious user. The end user will now see Unauthorized instead of + AccountLocked, preventing user info oracle exploitation.
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- github.com/advisories/GHSA-4225-97pr-rr52ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-38155ghsaADVISORY
- www.openwall.com/lists/oss-security/2021/08/10/5ghsamailing-listWEB
- github.com/openstack/keystone/commit/1b573ae7d1c20e0ebfbde79bbe7538a09589c75dghsaWEB
- github.com/openstack/keystone/commit/8ab4eb27be4c13c9bab2b3ea700f00a190521bf8ghsaWEB
- github.com/openstack/keystone/commit/ac2631ae33445877094cdae796fbcdce8833a626ghsaWEB
- launchpad.net/bugs/1688137ghsaWEB
- lists.debian.org/debian-lts-announce/2024/01/msg00007.htmlghsamailing-listWEB
- security.openstack.org/ossa/OSSA-2021-003.htmlghsaWEB
News mentions
0No linked articles in our index yet.