1
Description: Require authz for user role list
2
Jason Xu (yinyangxu@gmail.com) discovered several vulnerabilities in OpenStack
3
Keystone token verification:
5
The first occurs in the API /v2.0/OS-KSADM/services and
6
/v2.0/OS-KSADM/services/{service_id}, the second occurs in
7
/v2.0/tenants/{tenant_id}/users/{user_id}/roles
9
In both cases the OpenStack Keystone code fails to check if the tokens are
10
valid. These issues have been addressed by adding checks in the form of
11
test_service_crud_requires_auth() and test_user_role_list_requires_auth().
12
Bug-Debian: http://bugs.debian.org/689210
13
Bug-Ubuntu: https://bugs.launchpad.net/+bug/1006815
14
Author: Dolph Mathews <dolph.mathews@gmail.com>
17
Index: keystone/keystone/identity/core.py
18
===================================================================
19
--- keystone.orig/keystone/identity/core.py 2012-10-01 06:25:52.000000000 +0000
20
+++ keystone/keystone/identity/core.py 2012-10-01 06:25:52.000000000 +0000
22
not implementing them in hopes that the idea will die off.
25
+ self.assert_admin(context)
27
raise exception.NotImplemented(message='User roles not supported: '
29
Index: keystone/tests/test_content_types.py
30
===================================================================
31
--- keystone.orig/tests/test_content_types.py 2012-10-01 06:25:48.000000000 +0000
32
+++ keystone/tests/test_content_types.py 2012-10-01 06:25:52.000000000 +0000
39
from lxml import etree
42
def assertValidVersionResponse(self, r):
43
self.assertValidVersion(r.body.get('version'))
45
+ def test_user_role_list_requires_auth(self):
46
+ """User role list should 401 without an X-Auth-Token (bug 1006815)."""
47
+ # values here don't matter because we should 401 before they're checked
48
+ path = '/v2.0/tenants/%(tenant_id)s/users/%(user_id)s/roles' % {
49
+ 'tenant_id': uuid.uuid4().hex,
50
+ 'user_id': uuid.uuid4().hex,
53
+ r = self.admin_request(path=path, expected_status=401)
54
+ self.assertValidErrorResponse(r)
56
+ def test_service_crud_requires_auth(self):
57
+ """Service CRUD should 401 without an X-Auth-Token (bug 1006822)."""
58
+ # values here don't matter because we should 401 before they're checked
59
+ service_path = '/v2.0/OS-KSADM/services/%s' % uuid.uuid4().hex
61
+ 'OS-KSADM:service': {
62
+ 'name': uuid.uuid4().hex,
63
+ 'type': uuid.uuid4().hex,
67
+ r = self.admin_request(method='GET',
68
+ path='/v2.0/OS-KSADM/services',
69
+ expected_status=401)
70
+ self.assertValidErrorResponse(r)
72
+ r = self.admin_request(method='POST',
73
+ path='/v2.0/OS-KSADM/services',
75
+ expected_status=401)
76
+ self.assertValidErrorResponse(r)
78
+ r = self.admin_request(method='GET',
80
+ expected_status=401)
81
+ self.assertValidErrorResponse(r)
83
+ r = self.admin_request(method='DELETE',
85
+ expected_status=401)
86
+ self.assertValidErrorResponse(r)
89
class XmlTestCase(RestfulTestCase, CoreApiTests):
90
xmlns = 'http://docs.openstack.org/identity/api/v2.0'
91
Index: keystone/keystone/catalog/core.py
92
===================================================================
93
--- keystone.orig/keystone/catalog/core.py 2012-10-01 06:25:48.000000000 +0000
94
+++ keystone/keystone/catalog/core.py 2012-10-01 06:25:52.000000000 +0000
96
class ServiceController(wsgi.Application):
98
self.catalog_api = Manager()
99
+ self.identity_api = identity.Manager()
100
+ self.policy_api = policy.Manager()
101
+ self.token_api = token.Manager()
102
super(ServiceController, self).__init__()
105
# NOTE(termie): this OS-KSADM stuff is not very consistent
106
def get_services(self, context):
107
+ self.assert_admin(context)
108
service_list = self.catalog_api.list_services(context)
109
service_refs = [self.catalog_api.get_service(context, x)
110
for x in service_list]
111
return {'OS-KSADM:services': service_refs}
113
def get_service(self, context, service_id):
114
+ self.assert_admin(context)
115
service_ref = self.catalog_api.get_service(context, service_id)
117
raise exception.ServiceNotFound(service_id=service_id)
118
return {'OS-KSADM:service': service_ref}
120
def delete_service(self, context, service_id):
121
+ self.assert_admin(context)
122
service_ref = self.catalog_api.get_service(context, service_id)
124
raise exception.ServiceNotFound(service_id=service_id)
125
self.catalog_api.delete_service(context, service_id)
127
def create_service(self, context, OS_KSADM_service):
128
+ self.assert_admin(context)
129
service_id = uuid.uuid4().hex
130
service_ref = OS_KSADM_service.copy()
131
service_ref['id'] = service_id