Limit token expiration to application credential expiration
If a token is issued with an application credential we need to check
the expiration of the application credential to ensure that the token
does not outlive the application credential. This ensures that if the
token expiration is greaten than that of the application credential it
is reset to the expiration of the application credential and a warning
is logged. Please see CVE-2022-2447 for more information.
Closes-Bug: 1992183
Change-Id: If6f9f72cf25769d022a970fac36cead17b2030f2
(cherry picked from commit 8f999d1c1f
)
This commit is contained in:
parent
a26b9c20de
commit
164d9522b8
|
@ -5577,6 +5577,21 @@ class ApplicationCredentialAuth(test_v3.RestfulTestCase):
|
|||
self.v3_create_token(auth_data,
|
||||
expected_status=http.client.UNAUTHORIZED)
|
||||
|
||||
def test_application_credential_expiration_limits_token_expiration(self):
|
||||
expires_at = datetime.datetime.utcnow() + datetime.timedelta(minutes=1)
|
||||
app_cred = self._make_app_cred(expires=expires_at)
|
||||
app_cred_ref = self.app_cred_api.create_application_credential(
|
||||
app_cred)
|
||||
auth_data = self.build_authentication_request(
|
||||
app_cred_id=app_cred_ref['id'], secret=app_cred_ref['secret'])
|
||||
resp = self.v3_create_token(auth_data,
|
||||
expected_status=http.client.CREATED)
|
||||
token = resp.headers.get('X-Subject-Token')
|
||||
future = datetime.datetime.utcnow() + datetime.timedelta(minutes=2)
|
||||
with freezegun.freeze_time(future):
|
||||
self._validate_token(token,
|
||||
expected_status=http.client.UNAUTHORIZED)
|
||||
|
||||
def test_application_credential_fails_when_user_deleted(self):
|
||||
app_cred = self._make_app_cred()
|
||||
app_cred_ref = self.app_cred_api.create_application_credential(
|
||||
|
|
|
@ -267,6 +267,23 @@ class Manager(manager.Manager):
|
|||
default_expire_time(), subsecond=True
|
||||
)
|
||||
|
||||
# NOTE(d34dh0r53): If this token is being issued with an application
|
||||
# credential and the application credential expires before the token
|
||||
# we need to set the token expiration to be the same as the application
|
||||
# credential. See CVE-2022-2447 for more information.
|
||||
if app_cred_id is not None:
|
||||
app_cred_api = PROVIDERS.application_credential_api
|
||||
app_cred = app_cred_api.get_application_credential(
|
||||
token.application_credential_id)
|
||||
token_time = timeutils.normalize_time(
|
||||
timeutils.parse_isotime(token.expires_at))
|
||||
if (app_cred['expires_at'] is not None) and (
|
||||
token_time > app_cred['expires_at']):
|
||||
token.expires_at = app_cred['expires_at'].isoformat()
|
||||
LOG.debug('Resetting token expiration to the application'
|
||||
' credential expiration: %s',
|
||||
app_cred['expires_at'].isoformat())
|
||||
|
||||
token_id, issued_at = self.driver.generate_id_and_issued_at(token)
|
||||
token.mint(token_id, issued_at)
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
security:
|
||||
- |
|
||||
[`bug 1992183 <https://bugs.launchpad.net/keystone/+bug/1992183>`_]
|
||||
[`CVE-2022-2447 <http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-2447>`_]
|
||||
Tokens issued with application credentials will now have their expiration
|
||||
validated against that of the application credential. If the application
|
||||
credential expires before the token the token's expiration will be set to
|
||||
the same expiration as the application credential. Otherwise the token
|
||||
will use the configured value.
|
Loading…
Reference in New Issue