[OSSA 2013-035] Heat ReST API doesn't respect tenant scoping (CVE-2013-6428)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
OpenStack Heat |
Fix Released
|
Critical
|
Steven Hardy | ||
Grizzly |
Won't Fix
|
Critical
|
Steven Hardy | ||
Havana |
Fix Released
|
Critical
|
Steven Hardy | ||
OpenStack Security Advisory |
Fix Released
|
Critical
|
Jeremy Stanley |
Bug Description
While working on the request-
https:/
Here we incorrectly override the request context tenant_id (which is what we get from the keystone auth_token middleware) with the tenant_id in the request path.
This has the very bad side effect of meaning that anyone who can authenticate with the Heat ReST API can just change the path and trivially bypass the tenant scoping of the request.
Steps to reproduce:
- Optionally set token_format = UUID in /etc/keystone/
- Create two users, User1 and User2, in two different tenants
- Create some heat stacks with each user
- Do heat --debug stack-list with each user and note the stack IDs
- Copy one of the curl commands and modify the path to point at the other tenant
- Observe that e.g User1 can retrieve stacks from User2's tenant
# keystone user-get User1
+------
| Property | Value |
+------
| email | |
| enabled | True |
| id | 36686aebcb0347c
| name | User1 |
| tenantId | 0809343a8f9e4f0
+------
# keystone user-get User2
+------
| Property | Value |
+------
| email | |
| enabled | True |
| id | 30c0207e25254a6
| name | User2 |
| tenantId | e638f4841a76428
+------
(keystone_User1)]$ heat list
+------
| id | stack_name | stack_status | creation_time |
+------
| a6a13511-
| 44eb22a2-
+------
(keystone_User2)]$ heat list
+------
| id | stack_name | stack_status | creation_time |
+------
| d26227b0-
+------
curl -i -X GET -H 'X-Auth-Token: 40ed9682a7f5423
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 1085
Date: Mon, 02 Dec 2013 16:41:41 GMT
{"stacks": [{"description": "Hello world HOT template that just defines a single compute instance. Contains just base features to verify base HOT support.\n", "links": [{"href": "http://
$ curl -i -X GET -H 'X-Auth-Token: 40ed9682a7f5423
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 554
Date: Mon, 02 Dec 2013 16:43:31 GMT
{"stacks": [{"description": "Hello world HOT template that just defines a single compute instance. Contains just base features to verify base HOT support.\n", "links": [{"href": "http://
Note the exact same X-Auth-Token is used in both cases, one from User1, but we can list User2's stack just by changing the path :(
CVE References
Changed in heat: | |
status: | New → In Progress |
assignee: | nobody → Steven Hardy (shardy) |
importance: | Undecided → Critical |
milestone: | none → icehouse-1 |
tags: | added: grizzly-backport-potential havana-backport-potential |
Changed in ossa: | |
status: | Incomplete → Confirmed |
assignee: | nobody → Jeremy Stanley (fungi) |
importance: | Undecided → Critical |
Changed in ossa: | |
status: | Confirmed → In Progress |
summary: |
- Heat ReST API doesn't respect tenant scoping + Heat ReST API doesn't respect tenant scoping (CVE-2013-6428) |
Changed in ossa: | |
status: | In Progress → Fix Committed |
information type: | Private Security → Public Security |
Changed in heat: | |
assignee: | Jeremy Stanley (fungi) → nobody |
summary: |
- Heat ReST API doesn't respect tenant scoping (CVE-2013-6428) + [OSSA 2013-035] Heat ReST API doesn't respect tenant scoping + (CVE-2013-6428) |
Changed in heat: | |
assignee: | nobody → Steven Hardy (shardy) |
Changed in ossa: | |
status: | Fix Committed → Fix Released |
Changed in heat: | |
status: | Fix Committed → Fix Released |
tags: | removed: grizzly-backport-potential havana-backport-potential |
Changed in heat: | |
milestone: | icehouse-2 → 2014.1 |
So the simplest possible fix is to remove the line which overwrites the context tenant_id:
https:/ /github. com/openstack/ heat/blob/ master/ heat/api/ openstack/ v1/util. py#L29
This just means the tenant_id in the path is ignored, and User1 always gets the same data regardless of the tenant specified in the path (solving the immediate problem)
However we should probably consider a more robust fix, where we deny any request where the tenant_id specified in the path doesn't match the tenant_id in the context, either directly in the API, or via a policy rule (I'm working on making the ReST API policy.json aware atm).