[OSSA 2014-026] Revocation events are broken with mysql (CVE-2014-5251)

Bug #1347961 reported by Brant Knudson
256
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Identity (keystone)
Fix Released
High
Brant Knudson
Icehouse
Fix Released
High
Brant Knudson
OpenStack Security Advisory
Fix Released
High
Tristan Cacqueray

Bug Description

Since mysql only stores timestamps with an accuracy of seconds rather than microseconds, doing comparisons of token expiration times will fail and tokens will not show up as being revoked.

Revision history for this message
Brant Knudson (blk-u) wrote :

A breakpoint in keystone/contrib/revoke/model.py, is_revoked():

mysql:

(Pdb) p self.revoke_map
{'trust_id=*': {'consumer_id=*': {'access_token_id=*': {'expires_at=2014-07-22 22:55:53': {'domain_id=*': {'project_id=*': {u'user_id=949c28307de74cafb4ab07c6ada75d6c': {'role_id=*': {'issued_before': datetime.datetime(2014, 7, 22, 21, 55, 59, 610579)}}}}}}}}}

DB2:

(Pdb) p self.revoke_map
{'trust_id=*': {'consumer_id=*': {'access_token_id=*': {'expires_at=2014-07-22 22:58:44.322976': {'domain_id=*': {'project_id=*': {u'user_id=c4ed3fa9ee5f4e02b580389400a817e0': {'role_id=*': {'issued_before': datetime.datetime(2014, 7, 22, 21, 58, 49, 390556)}}}}}}}}}

Revision history for this message
Brant Knudson (blk-u) wrote :

This is in add_event in model.py:

mysql:

(Pdb) event.expires_at
datetime.datetime(2014, 7, 22, 23, 28, 2)

db2:

(Pdb) event.expires_at
datetime.datetime(2014, 7, 22, 23, 22, 40, 481090)

Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

This looks like something we might be able to fix with a SQL migration to make the column a DATETIME(6) instead of DATETIME(0) (0 is the default in MySQL, where the SQL standard is datetime(6) http://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html )

Changed in keystone:
status: New → Triaged
importance: Undecided → High
Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

Marking this as a high priority as we have some large features that will rely on revocation events during the Juno cycle.

Changed in keystone:
milestone: none → juno-3
Revision history for this message
Brant Knudson (blk-u) wrote :

This is a security vulnerability since tokens aren't being revoked as they should be.

information type: Public → Public Security
Revision history for this message
Tristan Cacqueray (tristan-cacqueray) wrote :

@Brant, just to clarify, with a mysql token backend, token never expired ?

Also, do you know if icehouse/havana are also impacted ?

Changed in ossa:
status: New → Incomplete
Revision history for this message
Brant Knudson (blk-u) wrote :

@Tristan - I have to look into this more to be able to answer the question. All I can say is that when working with mysql the data isn't being returned on the query in the expected format.

This would only impact icehouse since revocation events were added in icehouse.

Revision history for this message
Brant Knudson (blk-u) wrote :

OK. I tried a test and I think this is legitimate and that tokens aren't getting expired.

To test this I modified the existing tempest test[1], to add a self.client.delete_token(token_id) right after the scoped token is revoked. This should revoke the unscoped token.

Then I changed the Keystone configuration so that it uses revocation events only, by setting revoke_by_id=false in keystone.conf

When running the test, the unscoped token IS NOT revoked. Looking at the debugger, after the revocations, the revocation event's self.revoke_map has ...'expires_at=2014-07-31 20:13:06'...

And the token data has 'expires_at': datetime.datetime(2014, 7, 31, 20, 13, 6, 126800). So is_revoked tries to match 'expires_at=2014-07-31 20:13:06.126800' against the revoke_map and it doesn't match because it's an exact match.

[1] http://git.openstack.org/cgit/openstack/tempest/tree/tempest/api/identity/admin/v3/test_tokens.py?id=973c6cd98e4b226bec2f1b40943afaa910e18047#n140

Essentially, revoking tokens individually doesn't work with mysql and revocation events.

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to keystone (master)

Fix proposed to branch: master
Review: https://review.openstack.org/111106

Changed in keystone:
assignee: nobody → Brant Knudson (blk-u)
status: Triaged → In Progress
Changed in ossa:
status: Incomplete → Confirmed
assignee: nobody → Tristan Cacqueray (tristan-cacqueray)
importance: Undecided → High
Revision history for this message
Tristan Cacqueray (tristan-cacqueray) wrote : Re: Revocation events are broken with mysql

Title: Token does not expire or revoke with Mysql backend
Reporter: Brant Knudson (IBM)
Products: Keystone
Versions: 2014.1.1

Description:
Brant Knudson from IBM reported a vulnerability in Keystone revocation events. Mysql does not store expiration date correctly resulting in tokens to never expire and breaking manual revocation. Only Keystone setups configured to use revocation events and Mysql tokens backend are affected.

Revision history for this message
Brant Knudson (blk-u) wrote :

The impact statement isn't correct since it says that tokens won't expire using MySQL, but they will. It just that revocations don't work with revocation events at all. Here's my attempt:

Brant Knudson from IBM reported a vulnerability in Keystone revocation events. The Keystone revocation events code expects the database to store expiration timestamps with subsecond accuracy, which Mysql does not do. This causes tokens that are manually revoked to remain valid. Only Keystone setups configured to use revocation events and the SQL token driver with MySQL are affected.

Revision history for this message
Tristan Cacqueray (tristan-cacqueray) wrote :

@Brant thanks again for those reviews, here is a more simplified description considering revocations events are very recent and that no keystone middleware supporting those have been released yet...

So here is the combined impact description for bugs #1348820, #1347961, #1349597:

Title: Multiple vulnerabilities in Keystone revocation events
Reporter: Lance Bragstad (Rackspace) and Brant Knudson (IBM)
Products: Keystone
Versions: 2014.1.1

Description:
Lance Bragstad from Rackspace and Brant Knudson from IBM reported 3 vulnerabilities in Keystone revocations events. Lance Bragstad discovered that UUID v2 tokens processed by the V3 API are incorectly updated and get their "issued_at" time regenerated. Brant Knudson discovered that Mysql token driver stores expiration date incorrectly which prevent manual revocation and that domain-scoped tokens don't get revoked when the domain is disabled. Tokens impacted by one of those bug may allow a user to evade token revocation. Only Keystone setups configured to use revocations events are affected.

Revision history for this message
Brant Knudson (blk-u) wrote :

Comments on the impact statement in comment #12:

change "revocations events" to "revocation events" (remove s, this is at the beginning and at the end of the text)

change "that Mysql token" to "that the MySQL token" (add the)

change "expiration date incorrectly" to "expiration dates incorrectly" (add s)

change "which prevent manual" to "which prevents manual" (add s)

change "those bug may" to "these bugs may"

Revision history for this message
Tristan Cacqueray (tristan-cacqueray) wrote :

Thanks Brant!
Here is the revised version:

Title: Multiple vulnerabilities in Keystone revocation events
Reporter: Lance Bragstad (Rackspace) and Brant Knudson (IBM)
Products: Keystone
Versions: 2014.1.1

Description:
Lance Bragstad from Rackspace and Brant Knudson from IBM reported 3 vulnerabilities in Keystone revocation events. Lance Bragstad discovered that UUID v2 tokens processed by the V3 API are incorectly updated and get their "issued_at" time regenerated. Brant Knudson discovered that the MySQL token driver stores expiration dates incorrectly which prevents manual revocation and that domain-scoped tokens don't get revoked when the domain is disabled. Tokens impacted by one of these bugs may allow a user to evade token revocation. Only Keystone setups configured to use revocation events are affected.

Revision history for this message
Brant Knudson (blk-u) wrote :

change "incorectly" to "incorrectly"

Revision history for this message
Brant Knudson (blk-u) wrote :

should say other than that the impact statement looks good to me.

Revision history for this message
Thierry Carrez (ttx) wrote :

Impact desc looks good; except "Versions" should probably read "2014.1 versions up to 2014.1.1"

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to keystone (master)

Reviewed: https://review.openstack.org/111106
Committed: https://git.openstack.org/cgit/openstack/keystone/commit/?id=7aee6304f653475a4130dc3e5be602e91481f108
Submitter: Jenkins
Branch: master

commit 7aee6304f653475a4130dc3e5be602e91481f108
Author: Brant Knudson <email address hidden>
Date: Thu Jul 31 17:47:00 2014 -0500

    Fix revocation event handling with MySQL

    When MySQL is used to store revocation events, events are returned
    from the database with the timestamps truncated to the second. This
    causes a revocation event for a token (which has the issued_at
    timestamp to the microsecond) to not match the revocation event and
    therefore the token is not considered to be revoked.

    The fix is to have the revocation events and token timestamps both
    always be truncated to the second. This will cause all tokens for a
    user that are issued within a second to be revoked when any of those
    tokens are revoked, which shouldn't be a problem.

    Change-Id: Ibd82b4ce910206dfd504c396614ae2ebed025e9b
    Closes-Bug: #1347961

Changed in keystone:
status: In Progress → Fix Committed
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to keystone (stable/icehouse)

Fix proposed to branch: stable/icehouse
Review: https://review.openstack.org/112087

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to keystone (stable/icehouse)

Reviewed: https://review.openstack.org/112087
Committed: https://git.openstack.org/cgit/openstack/keystone/commit/?id=6cbf835542d62e6e5db4b4aef7141b1731cad9dc
Submitter: Jenkins
Branch: stable/icehouse

commit 6cbf835542d62e6e5db4b4aef7141b1731cad9dc
Author: Brant Knudson <email address hidden>
Date: Thu Jul 31 17:47:00 2014 -0500

    Fix revocation event handling with MySQL

    When MySQL is used to store revocation events, events are returned
    from the database with the timestamps truncated to the second. This
    causes a revocation event for a token (which has the issued_at
    timestamp to the microsecond) to not match the revocation event and
    therefore the token is not considered to be revoked.

    The fix is to have the revocation events and token timestamps both
    always be truncated to the second. This will cause all tokens for a
    user that are issued within a second to be revoked when any of those
    tokens are revoked, which shouldn't be a problem.

    Conflicts:

     keystone/tests/test_v3_os_revoke.py

    Change-Id: Ibd82b4ce910206dfd504c396614ae2ebed025e9b
    Closes-Bug: #1347961
    (cherry picked from commit 7aee6304f653475a4130dc3e5be602e91481f108)

Thierry Carrez (ttx)
Changed in ossa:
status: Confirmed → Triaged
Thierry Carrez (ttx)
Changed in ossa:
status: Triaged → In Progress
summary: - Revocation events are broken with mysql
+ Revocation events are broken with mysql (CVE-2014-5251)
summary: - Revocation events are broken with mysql (CVE-2014-5251)
+ [OSSA 2014-026] Revocation events are broken with mysql (CVE-2014-5251)
Changed in ossa:
status: In Progress → Fix Released
Thierry Carrez (ttx)
Changed in keystone:
status: Fix Committed → Fix Released
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to keystone (master)

Fix proposed to branch: master
Review: https://review.openstack.org/121711

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Change abandoned on keystone (master)

Change abandoned by Ryan Hsu (<email address hidden>) on branch: master
Review: https://review.openstack.org/121711
Reason: Testing

Thierry Carrez (ttx)
Changed in keystone:
milestone: juno-3 → 2014.2
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.