High severityNVD Advisory· Published Oct 9, 2012· Updated Apr 29, 2026
CVE-2012-4456
CVE-2012-4456
Description
The (1) OS-KSADM/services and (2) tenant APIs in OpenStack Keystone Essex before 2012.1.2 and Folsom before folsom-2 do not properly validate X-Auth-Token, which allow remote attackers to read the roles for an arbitrary user or get, create, or delete arbitrary services.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
keystonePyPI | >= 2012.1, < 2012.1.2 | 2012.1.2 |
Affected products
2Patches
4868054992faaRequire authz for user role list (bug 1006815)
2 files changed · +12 −0
keystone/identity/core.py+1 −0 modified@@ -467,6 +467,7 @@ def get_user_roles(self, context, user_id, tenant_id=None): not implementing them in hopes that the idea will die off. """ + self.assert_admin(context) if tenant_id is None: raise exception.NotImplemented(message='User roles not supported: ' 'tenant ID required')
tests/test_content_types.py+11 −0 modified@@ -587,6 +587,17 @@ def test_service_crud_requires_auth(self): expected_status=401) self.assertValidErrorResponse(r) + def test_user_role_list_requires_auth(self): + """User role list should 401 without an X-Auth-Token (bug 1006815).""" + # values here don't matter because we should 401 before they're checked + path = '/v2.0/tenants/%(tenant_id)s/users/%(user_id)s/roles' % { + 'tenant_id': uuid.uuid4().hex, + 'user_id': uuid.uuid4().hex, + } + + r = self.admin_request(path=path, expected_status=401) + self.assertValidErrorResponse(r) + class XmlTestCase(RestfulTestCase, CoreApiTests): xmlns = 'http://docs.openstack.org/identity/api/v2.0'
14b136aed9d9Require authz for user role list (bug 1006815)
2 files changed · +12 −0
keystone/identity/core.py+1 −0 modified@@ -457,6 +457,7 @@ def get_user_roles(self, context, user_id, tenant_id=None): not implementing them in hopes that the idea will die off. """ + self.assert_admin(context) if tenant_id is None: raise exception.NotImplemented(message='User roles not supported: ' 'tenant ID required')
tests/test_content_types.py+11 −0 modified@@ -587,6 +587,17 @@ def test_service_crud_requires_auth(self): expected_status=401) self.assertValidErrorResponse(r) + def test_user_role_list_requires_auth(self): + """User role list should 401 without an X-Auth-Token (bug 1006815).""" + # values here don't matter because we should 401 before they're checked + path = '/v2.0/tenants/%(tenant_id)s/users/%(user_id)s/roles' % { + 'tenant_id': uuid.uuid4().hex, + 'user_id': uuid.uuid4().hex, + } + + r = self.admin_request(path=path, expected_status=401) + self.assertValidErrorResponse(r) + class XmlTestCase(RestfulTestCase, CoreApiTests): xmlns = 'http://docs.openstack.org/identity/api/v2.0'
1d146f5c32e5Require authz for service CRUD (bug 1006822)
2 files changed · +40 −0
keystone/catalog/core.py+7 −0 modified@@ -116,29 +116,36 @@ def get_catalog(self, user_id, tenant_id, metadata=None): class ServiceController(wsgi.Application): def __init__(self): self.catalog_api = Manager() + self.identity_api = identity.Manager() + self.policy_api = policy.Manager() + self.token_api = token.Manager() super(ServiceController, self).__init__() # CRUD extensions # NOTE(termie): this OS-KSADM stuff is not very consistent def get_services(self, context): + self.assert_admin(context) service_list = self.catalog_api.list_services(context) service_refs = [self.catalog_api.get_service(context, x) for x in service_list] return {'OS-KSADM:services': service_refs} def get_service(self, context, service_id): + self.assert_admin(context) service_ref = self.catalog_api.get_service(context, service_id) if not service_ref: raise exception.ServiceNotFound(service_id=service_id) return {'OS-KSADM:service': service_ref} def delete_service(self, context, service_id): + self.assert_admin(context) service_ref = self.catalog_api.get_service(context, service_id) if not service_ref: raise exception.ServiceNotFound(service_id=service_id) self.catalog_api.delete_service(context, service_id) def create_service(self, context, OS_KSADM_service): + self.assert_admin(context) service_id = uuid.uuid4().hex service_ref = OS_KSADM_service.copy() service_ref['id'] = service_id
tests/test_content_types.py+33 −0 modified@@ -16,6 +16,7 @@ import httplib import json +import uuid from lxml import etree import nose.exc @@ -554,6 +555,38 @@ def assertValidMultipleChoiceResponse(self, r): def assertValidVersionResponse(self, r): self.assertValidVersion(r.body.get('version')) + def test_service_crud_requires_auth(self): + """Service CRUD should 401 without an X-Auth-Token (bug 1006822).""" + # values here don't matter because we should 401 before they're checked + service_path = '/v2.0/OS-KSADM/services/%s' % uuid.uuid4().hex + service_body = { + 'OS-KSADM:service': { + 'name': uuid.uuid4().hex, + 'type': uuid.uuid4().hex, + }, + } + + r = self.admin_request(method='GET', + path='/v2.0/OS-KSADM/services', + expected_status=401) + self.assertValidErrorResponse(r) + + r = self.admin_request(method='POST', + path='/v2.0/OS-KSADM/services', + body=service_body, + expected_status=401) + self.assertValidErrorResponse(r) + + r = self.admin_request(method='GET', + path=service_path, + expected_status=401) + self.assertValidErrorResponse(r) + + r = self.admin_request(method='DELETE', + path=service_path, + expected_status=401) + self.assertValidErrorResponse(r) + class XmlTestCase(RestfulTestCase, CoreApiTests): xmlns = 'http://docs.openstack.org/identity/api/v2.0'
24df3adb3f50Require authz for service CRUD (bug 1006822)
2 files changed · +40 −0
keystone/catalog/core.py+7 −0 modified@@ -116,29 +116,36 @@ def get_catalog(self, user_id, tenant_id, metadata=None): class ServiceController(wsgi.Application): def __init__(self): self.catalog_api = Manager() + self.identity_api = identity.Manager() + self.policy_api = policy.Manager() + self.token_api = token.Manager() super(ServiceController, self).__init__() # CRUD extensions # NOTE(termie): this OS-KSADM stuff is not very consistent def get_services(self, context): + self.assert_admin(context) service_list = self.catalog_api.list_services(context) service_refs = [self.catalog_api.get_service(context, x) for x in service_list] return {'OS-KSADM:services': service_refs} def get_service(self, context, service_id): + self.assert_admin(context) service_ref = self.catalog_api.get_service(context, service_id) if not service_ref: raise exception.ServiceNotFound(service_id=service_id) return {'OS-KSADM:service': service_ref} def delete_service(self, context, service_id): + self.assert_admin(context) service_ref = self.catalog_api.get_service(context, service_id) if not service_ref: raise exception.ServiceNotFound(service_id=service_id) self.catalog_api.delete_service(context, service_id) def create_service(self, context, OS_KSADM_service): + self.assert_admin(context) service_id = uuid.uuid4().hex service_ref = OS_KSADM_service.copy() service_ref['id'] = service_id
tests/test_content_types.py+33 −0 modified@@ -16,6 +16,7 @@ import httplib import json +import uuid from lxml import etree import nose.exc @@ -554,6 +555,38 @@ def assertValidMultipleChoiceResponse(self, r): def assertValidVersionResponse(self, r): self.assertValidVersion(r.body.get('version')) + def test_service_crud_requires_auth(self): + """Service CRUD should 401 without an X-Auth-Token (bug 1006822).""" + # values here don't matter because we should 401 before they're checked + service_path = '/v2.0/OS-KSADM/services/%s' % uuid.uuid4().hex + service_body = { + 'OS-KSADM:service': { + 'name': uuid.uuid4().hex, + 'type': uuid.uuid4().hex, + }, + } + + r = self.admin_request(method='GET', + path='/v2.0/OS-KSADM/services', + expected_status=401) + self.assertValidErrorResponse(r) + + r = self.admin_request(method='POST', + path='/v2.0/OS-KSADM/services', + body=service_body, + expected_status=401) + self.assertValidErrorResponse(r) + + r = self.admin_request(method='GET', + path=service_path, + expected_status=401) + self.assertValidErrorResponse(r) + + r = self.admin_request(method='DELETE', + path=service_path, + expected_status=401) + self.assertValidErrorResponse(r) + class XmlTestCase(RestfulTestCase, CoreApiTests): xmlns = 'http://docs.openstack.org/identity/api/v2.0'
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
17- www.openwall.com/lists/oss-security/2012/09/28/5nvdMailing ListPatchThird Party AdvisoryWEB
- bugs.launchpad.net/keystone/+bug/1006822nvdPatchThird Party AdvisoryWEB
- lists.launchpad.net/openstack/msg17034.htmlnvdPatchThird Party AdvisoryWEB
- secunia.com/advisories/50665nvdThird Party AdvisoryVendor Advisory
- www.securityfocus.com/bid/55716nvdThird Party AdvisoryVDB Entry
- bugs.launchpad.net/keystone/+bug/1006815nvdThird Party AdvisoryWEB
- bugzilla.redhat.com/show_bug.cginvdIssue TrackingThird Party AdvisoryWEB
- exchange.xforce.ibmcloud.com/vulnerabilities/78944nvdThird Party AdvisoryVDB EntryWEB
- github.com/advisories/GHSA-mf98-r2gf-2x3wghsaADVISORY
- github.com/openstack/keystone/commit/14b136aed9d988f5a8f3e699bd4577c9b874d6c1nvdThird Party AdvisoryWEB
- github.com/openstack/keystone/commit/1d146f5c32e58a73a677d308370f147a3271c2cbnvdThird Party AdvisoryWEB
- github.com/openstack/keystone/commit/24df3adb3f50cbb5ada411bc67aba8a781e6a431nvdThird Party AdvisoryWEB
- github.com/openstack/keystone/commit/868054992faa45d6f42d822bf1588cb88d7c9ccbnvdThird Party AdvisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2012-4456ghsaADVISORY
- access.redhat.com/errata/RHSA-2012:1378ghsaWEB
- access.redhat.com/security/cve/CVE-2012-4456ghsaWEB
- web.archive.org/web/20121114024512/http://www.securityfocus.com/bid/55716ghsaWEB
News mentions
0No linked articles in our index yet.