yahoo-eng-team team mailing list archive
-
yahoo-eng-team team
-
Mailing list archive
-
Message #04949
[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