VYPR
Moderate severityNVD Advisory· Published Sep 18, 2012· Updated Apr 29, 2026

CVE-2012-4413

CVE-2012-4413

Description

OpenStack Keystone 2012.1.3 does not invalidate existing tokens when granting or revoking roles, which allows remote authenticated users to retain the privileges of the revoked roles.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
keystonePyPI
< 2012.1.32012.1.3

Affected products

1

Patches

1
58ac6691a216

Delete user tokens after role grant/revoke

https://github.com/openstack/keystoneDolph MathewsSep 7, 2012via ghsa
3 files changed · +26 10
  • keystone/identity/core.py+6 1 modified
    @@ -525,6 +525,8 @@ def add_role_to_user(self, context, user_id, role_id, tenant_id=None):
             self.identity_api.add_user_to_tenant(context, tenant_id, user_id)
             self.identity_api.add_role_to_user_and_tenant(
                     context, user_id, tenant_id, role_id)
    +        self.token_api.revoke_tokens(context, user_id)
    +
             role_ref = self.identity_api.get_role(context, role_id)
             return {'role': role_ref}
     
    @@ -555,7 +557,7 @@ def remove_role_from_user(self, context, user_id, role_id, tenant_id=None):
             if not roles:
                 self.identity_api.remove_user_from_tenant(
                         context, tenant_id, user_id)
    -        return
    +        self.token_api.revoke_tokens(context, user_id)
     
         # COMPAT(diablo): CRUD extension
         def get_role_refs(self, context, user_id):
    @@ -597,6 +599,8 @@ def create_role_ref(self, context, user_id, role):
             self.identity_api.add_user_to_tenant(context, tenant_id, user_id)
             self.identity_api.add_role_to_user_and_tenant(
                     context, user_id, tenant_id, role_id)
    +        self.token_api.revoke_tokens(context, user_id)
    +
             role_ref = self.identity_api.get_role(context, role_id)
             return {'role': role_ref}
     
    @@ -624,3 +628,4 @@ def delete_role_ref(self, context, user_id, role_ref_id):
             if not roles:
                 self.identity_api.remove_user_from_tenant(
                         context, tenant_id, user_id)
    +        self.token_api.revoke_tokens(context, user_id)
    
  • keystone/token/core.py+11 0 modified
    @@ -38,6 +38,10 @@ class Manager(manager.Manager):
         def __init__(self):
             super(Manager, self).__init__(CONF.token.driver)
     
    +    def revoke_tokens(self, context, user_id):
    +        for token_id in self.list_tokens(context, user_id):
    +            self.delete_token(context, token_id)
    +
     
     class Driver(object):
         """Interface description for a Token driver."""
    @@ -97,6 +101,13 @@ def list_tokens(self, user_id):
             """
             raise exception.NotImplemented()
     
    +    def revoke_tokens(self, user_id):
    +        """Invalidates all tokens held by a user.
    +
    +        :raises: keystone.exception.UserNotFound
    +        """
    +        raise exception.NotImplemented()
    +
         def _get_default_expire_time(self):
             """Determine when a token should expire based on the config.
     
    
  • tests/test_keystoneclient.py+9 9 modified
    @@ -769,15 +769,15 @@ def get_checkout(self):
         def test_tenant_add_and_remove_user(self):
             client = self.get_client(admin=True)
             client.roles.add_user_role(tenant=self.tenant_baz['id'],
    -                                   user=self.user_foo['id'],
    +                                   user=self.user_two['id'],
                                        role=self.role_useless['id'])
             user_refs = client.tenants.list_users(tenant=self.tenant_baz['id'])
    -        self.assert_(self.user_foo['id'] in [x.id for x in user_refs])
    +        self.assert_(self.user_two['id'] in [x.id for x in user_refs])
             client.roles.remove_user_role(tenant=self.tenant_baz['id'],
    -                                      user=self.user_foo['id'],
    +                                      user=self.user_two['id'],
                                           role=self.role_useless['id'])
             user_refs = client.tenants.list_users(tenant=self.tenant_baz['id'])
    -        self.assert_(self.user_foo['id'] not in [x.id for x in user_refs])
    +        self.assert_(self.user_two['id'] not in [x.id for x in user_refs])
     
         def test_user_role_add_404(self):
             from keystoneclient import exceptions as client_exceptions
    @@ -890,28 +890,28 @@ def get_checkout(self):
         def test_tenant_add_and_remove_user(self):
             client = self.get_client(admin=True)
             client.roles.add_user_to_tenant(tenant_id=self.tenant_baz['id'],
    -                                        user_id=self.user_foo['id'],
    +                                        user_id=self.user_two['id'],
                                             role_id=self.role_useless['id'])
             role_refs = client.roles.get_user_role_refs(
    -                user_id=self.user_foo['id'])
    +                user_id=self.user_two['id'])
             self.assert_(self.tenant_baz['id'] in [x.tenantId for x in role_refs])
     
             # get the "role_refs" so we get the proper id, this is how the clients
             # do it
             roleref_refs = client.roles.get_user_role_refs(
    -                user_id=self.user_foo['id'])
    +                user_id=self.user_two['id'])
             for roleref_ref in roleref_refs:
                 if (roleref_ref.roleId == self.role_useless['id']
                     and roleref_ref.tenantId == self.tenant_baz['id']):
                     # use python's scope fall through to leave roleref_ref set
                     break
     
             client.roles.remove_user_from_tenant(tenant_id=self.tenant_baz['id'],
    -                                             user_id=self.user_foo['id'],
    +                                             user_id=self.user_two['id'],
                                                  role_id=roleref_ref.id)
     
             role_refs = client.roles.get_user_role_refs(
    -                user_id=self.user_foo['id'])
    +                user_id=self.user_two['id'])
             self.assert_(self.tenant_baz['id'] not in
                          [x.tenantId for x in role_refs])
     
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

17

News mentions

0

No linked articles in our index yet.