[OSSA 2012-010] Once a token is created/distributed its expiry date can be circumvented

Bug #998185 reported by Derek Higgins on 2012-05-11
264
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Identity (keystone)
Medium
Derek Higgins
Essex
Undecided
Unassigned
OpenStack Security Advisory
Undecided
Thierry Carrez

Bug Description

When a token is distributed that is intended to expire, this expiry time
can be worked around by continuesly creating new tokens before the old one has
expired.

Effectively granting the holder of the token open ended access to a service.

For example (with expiration = 60 seconds)

# Create a token with username/password
 > date -u ; ./tools/with_venv.sh python ./keystoneclient/shell.py token-get
Fri May 11 17:43:00 UTC 2012
+-----------+----------------------------------+
| Property | Value |
+-----------+----------------------------------+
| expires | 2012-05-11T17:44:00Z |
| id | 6345d6fd276f4eba81927c42dad073ef |
| tenant_id | b0b68a8de4d141d7afbde2683ae1a075 |
| user_id | e20d930d58c44b1e89ea93593fc43413 |
+-----------+----------------------------------+

# Before this token expires create another
 > date -u ; curl -X POST http://127.0.0.1:5000/v2.0/tokens -d '{"auth": {"tenantName":"test", "token":{"id":"6345d6fd276f4eba81927c42dad073ef"}}}' -H 'Content-Type: application/json'

Fri May 11 17:43:50 UTC 2012
{"access": {"token": {"expires": "2012-05-11T17:44:50Z", "id": "d154f83ccfc64c95b49ada79370bffb5", "tenant": {"enabled": true, "id": "b0b68a8de4d141d7afbde2683ae1a075", "name": "test", "description": null}}, "serviceCatalog": {}, "user": {"username": "test", "roles_links": [], "id": "e20d930d58c44b1e89ea93593fc43413", "roles": [{"id": "81b6624332054062bd2a379539ff70a6", "name": "user"}], "name": "test"}}} >

# Continue this process as much as you want
 > date -u ; curl -X POST http://127.0.0.1:5000/v2.0/tokens -d '{"auth": {"tenantName":"test", "token":{"id":"d154f83ccfc64c95b49ada79370bffb5"}}}' -H 'Content-Type: application/json'

Fri May 11 17:44:41 UTC 2012
{"access": {"token": {"expires": "2012-05-11T17:45:41Z", "id": "47e3578b53914185bce05013905c1142", "tenant": {"enabled": true, "id": "b0b68a8de4d141d7afbde2683ae1a075", "name": "test", "description": null}}, "serviceCatalog": {}, "user": {"username": "test", "roles_links": [], "id": "e20d930d58c44b1e89ea93593fc43413", "roles": [{"id": "81b6624332054062bd2a379539ff70a6", "name": "user"}], "name": "test"}}} >

# The original token has now expired
 > date -u ; curl -X POST http://127.0.0.1:5000/v2.0/tokens -d '{"auth": {"tenantName":"test", "token":{"id":"6345d6fd276f4eba81927c42dad073ef"}}}' -H 'Content-Type: application/json'

Fri May 11 17:44:50 UTC 2012
{"error": {"message": "The request you have made requires authentication.", "code": 401, "title": "Not Authorized"}} >

# but I still have access to the system
 > date -u ; curl -X POST http://127.0.0.1:5000/v2.0/tokens -d '{"auth": {"tenantName":"test", "token":{"id":"47e3578b53914185bce05013905c1142"}}}' -H 'Content-Type: application/json'

Fri May 11 17:45:01 UTC 2012
{"access": {"token": {"expires": "2012-05-11T17:46:01Z", "id": "78b004b4a27c4b7d9a1abd26b4260b2a", "tenant": {"enabled": true, "id": "b0b68a8de4d141d7afbde2683ae1a075", "name": "test", "description": null}}, "serviceCatalog": {}, "user": {"username": "test", "roles_links": [], "id": "e20d930d58c44b1e89ea93593fc43413", "roles": [{"id": "81b6624332054062bd2a379539ff70a6", "name": "user"}], "name": "test"}}} >

To prevent this either
1) the code could be removed that allows tokens to be created from other tokens
or
2) a small change to carry over the expiration time between tokens could be added (retaining some compatibility with clients that use this functionality)

CVE References

Robert Clark (robert-clark) wrote :

I agree that this is a problem. Tokens timeout to limit the scope of abuse through compromise/loss. Allowing tokens to be extended or chained in this way does water down the protection somewhat but I don't think it's a big problem.

I could be wrong but I'd expect that the initial attack vector for this is to obtain a token and extend it before it expires. At that point an attacker could do any number of things to attack or modify this users settings via the API, perhaps having the same effect.

I'd like to understand where the requirement for chaining tokens like this came from before we take steps to limit/remove it as I expect doing so could break some applications that may rely on it currently.

Robert Clark (robert-clark) wrote :

@jheck, care to comment?

Joseph Heck (heckj) wrote :

I'm not 100% clear on the original reason behind the token-based auth and chaining, or even if that was a requirement. Adding dolphm and termie to this email - they may have more visibility into the original design decisions.

My understanding of the original pattern was that the implementors were already familiar with a token-based authentication mechanism from rackspace and architected the initial token mechanism to match that pattern, potentially identically.

Thierry Carrez (ttx) wrote :

@termie, Dolph: care to comment ?

Changed in keystone:
importance: Undecided → Medium
status: New → Confirmed
Dolph Mathews (dolph) wrote :

@heckj: The goal of chaining was to support re-scoping to a different tenant without passing full credentials each time. In the original use case: 1) pass in password credentials with no tenant, 2) receive an unscoped token, 3) call GET /tenants, and 4) re-auth with my token and tenant selection. This use case / pattern came from the OpenStack community as I recall, not rax.

I also believe keystone legacy followed the second pattern: re-authenticating with an existing token carried over the original expiry time.

Derek Higgins (derekh) wrote :

So is the best course of action here to maintain ability to re-auth with a tenant selection
but maintain the original expiry time.

Or should the code that allows token chaining be removed altogether?

Joseph Heck (heckj) wrote :

We can't remove the chaining without breaking backwards compatibility with the essex release and how folks are using it. A round 2 of the API should fully resolve this.

Let's open this bug to the public and track against an API v3 implementation where we can remove chaining

Thierry Carrez (ttx) wrote :

@Derek: please confirm you're OK with opening this bug as a "known weakness of the current design that should definitely be strengthened in future versions of the API"

Derek Higgins (derekh) wrote :

Yup I agree we can't remove chaining in this version of the API. How about the idea of maintaining the original expiry time? Do you feel that breaks backwards compatibility as well? I just wanted to get an opinion before I make a patch to do this.

If you're happy to make it public then I have no objection.

Thierry Carrez (ttx) wrote :

Opened.

visibility: private → public

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

Changed in keystone:
assignee: nobody → Derek Higgins (derekh)
status: Confirmed → In Progress
Alan Pevec (apevec) on 2012-06-05
tags: added: essex-backport

Reviewed: https://review.openstack.org/8174
Committed: http://github.com/openstack/keystone/commit/375838cfceb88cacc312ff6564e64eb18ee6a355
Submitter: Jenkins
Branch: master

commit 375838cfceb88cacc312ff6564e64eb18ee6a355
Author: Derek Higgins <email address hidden>
Date: Tue Jun 5 09:33:53 2012 +0100

    Carrying over token expiry time when token chaining

    Fixes bug #998185

    This commit causes the token expiry time to be maintained when
    one token is being created from another

    Change-Id: I7b61692a60d9227423b93c267864a5abe939ca33

Changed in keystone:
status: In Progress → Fix Committed

@Russell: retrospectively it looks like something we should communicate about... Do you think we should issue an OSSA about this ?

Russell Bryant (russellb) wrote :

Maybe we should just tag bugs that have changes that are worthy of specific mention in release notes?

Russell Bryant (russellb) wrote :

After looking at bug 997194 and bug 996595, I agree that an OSSA for all of these makes sense.

Reviewed: https://review.openstack.org/8573
Committed: http://github.com/openstack/keystone/commit/29e74e73a6e51cffc0371b32354558391826a4aa
Submitter: Jenkins
Branch: stable/essex

commit 29e74e73a6e51cffc0371b32354558391826a4aa
Author: Derek Higgins <email address hidden>
Date: Tue Jun 5 09:33:53 2012 +0100

    Carrying over token expiry time when token chaining

    Fixes bug #998185

    This commit causes the token expiry time to be maintained when
    one token is being created from another

    Change-Id: I7b61692a60d9227423b93c267864a5abe939ca33

Thierry Carrez (ttx) on 2012-07-04
Changed in keystone:
milestone: none → folsom-2
status: Fix Committed → Fix Released

Proposed retroactive common advisory:

Title: Various Keystone token expiration issues
Impact: Medium
Reporter: Derek Higgins
Products: Keystone
Affects: All versions

Description:
Derek Higgins reported various issues affecting Keystone token expiration. A token expiration date can be circumvented by continuously creating new tokens before the old one has expired. Existing tokens also remain valid after a user account is disabled or after an account password changed. An authenticated and authorized user could potentially leverage those vulnerabilities to extend his access beyond the account owner expectations.

Folsom fixes:
http://github.com/openstack/keystone/commit/375838cfceb88cacc312ff6564e64eb18ee6a355
http://github.com/openstack/keystone/commit/628149b3dc6b58b91fd08e6ca8d91c728ccb8626
http://github.com/openstack/keystone/commit/a67b24878a6156eab17b9098fa649f0279256f5d

Essex fixes:
http://github.com/openstack/keystone/commit/29e74e73a6e51cffc0371b32354558391826a4aa
http://github.com/openstack/keystone/commit/d9600434da14976463a0bd03abd8e0309f0db454
http://github.com/openstack/keystone/commit/ea03d05ed5de0c015042876100d37a6a14bf56de

Those fixes were included in Keystone 2012.1.1 stable update and the Folsom-1 development milestone.

References:
https://bugs.launchpad.net/keystone/+bug/998185
https://bugs.launchpad.net/keystone/+bug/997194
https://bugs.launchpad.net/keystone/+bug/996595

Russell Bryant (russellb) wrote :

Advisory looks good to me. Nice work, ttx.

Derek Higgins (derekh) wrote :

Looks good to me. Nice one.

Thierry Carrez (ttx) wrote :

Been assigned CVE-2012-3426

Thierry Carrez (ttx) on 2012-09-27
Changed in keystone:
milestone: folsom-2 → 2012.2
Thierry Carrez (ttx) on 2013-06-07
summary: - Once a token is created/distributed its expiry date can be circumvented
+ [OSSA 2012-010] Once a token is created/distributed its expiry date can
+ be circumvented
Changed in ossa:
assignee: nobody → Thierry Carrez (ttx)
status: New → Fix Released
To post a comment you must log in.
This report contains Public Security information  Edit
Everyone can see this security related information.

Other bug subscribers