← Back to team overview

yahoo-eng-team team mailing list archive

[Bug 1202952] Re: [OSSA 2013-025] PKI tokens are never revoked using memcache token backend (CVE-2013-4294)

 

Opening against master to forward port tests.

** Changed in: keystone
       Status: Invalid => Triaged

** Changed in: keystone
   Importance: Undecided => Wishlist

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to Keystone.
https://bugs.launchpad.net/bugs/1202952

Title:
  [OSSA 2013-025] PKI tokens are never revoked using memcache token
  backend (CVE-2013-4294)

Status in OpenStack Identity (Keystone):
  Triaged
Status in Keystone folsom series:
  In Progress
Status in Keystone grizzly series:
  In Progress
Status in OpenStack Security Advisories:
  Fix Committed

Bug description:
  This is a more serious incarnation of: https://bugs.launchpad.net/keystone/+bug/1202050.
  Looks to be fixed on master in c238ace30981877e5991874c5b193ea7d5107419 (id hashing happens keystone/token/core.py there).

  In the memcache token backend, whole tokens are stored in the
  revocation list.

  In keystone/token/backends.py:
  166     def _add_to_revocation_list(self, data):
  167         data_json = jsonutils.dumps(data)
  168         if not self.client.append(self.revocation_key, ',%s' % data_json):
  169             if not self.client.add(self.revocation_key, data_json):
  170                 if not self.client.append(self.revocation_key,
  171                                           ',%s' % data_json):
  172                     msg = _('Unable to add token to revocation list.')
  173                     raise exception.UnexpectedError(msg)
  174                     
  175     def delete_token(self, token_id):
  176         # Test for existence
  177         data = self.get_token(token_id)        <----
  178         ptk = self._prefix_token_id(token_id)
  179         result = self.client.delete(ptk)
  180         self._add_to_revocation_list(data)       <---- 
  181         return result

  And returned from the API when the auth_token middleware asks for the
  revocation list:

  208     def list_revoked_tokens(self):
  209         list_json = self.client.get(self.revocation_key)
  210         if list_json:
  211             return jsonutils.loads('[%s]' % list_json)
  212         return []

  The auth_token middleware hashes the signed token and searches the
  revocation list for the hash:

  1017     def is_signed_token_revoked(self, signed_text):
  1018         """Indicate whether the token appears in the revocation list."""
  1019         revocation_list = self.token_revocation_list
  1020         revoked_tokens = revocation_list.get('revoked', [])
  1021         if not revoked_tokens:
  1022             return
  1023         revoked_ids = (x['id'] for x in revoked_tokens)
  1024         token_id = utils.hash_signed_token(signed_text)
  1025         for revoked_id in revoked_ids:
  1026             if token_id == revoked_id:
  1027                 self.LOG.debug('Token %s is marked as having been revoked',
  1028                                token_id)
  1029                 return True
  1030         return False

  Because the memcache backend stores the entire token,  the value of
  x['id'] above is not an md5 hash, but the encoded PKI token. This will
  never match the value of the hashed untrusted token.

  Storing the whole token also means only around 256 tokens can stored
  before the memcache page is full and errors happen.

To manage notifications about this bug go to:
https://bugs.launchpad.net/keystone/+bug/1202952/+subscriptions