Moderate severityNVD Advisory· Published Nov 11, 2012· Updated Apr 29, 2026
CVE-2012-4573
CVE-2012-4573
Description
The v1 API in OpenStack Glance Grizzly, Folsom (2012.2), and Essex (2012.1) allows remote authenticated users to delete arbitrary non-protected images via an image deletion request, a different vulnerability than CVE-2012-5482.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
glancePyPI | < 11.0.0a0 | 11.0.0a0 |
Affected products
3- cpe:2.3:a:openstack:image_registry_and_delivery_service_\(glance\):-:*:*:*:*:*:*:*
Patches
3efd7e75b1f41Ensure image owned by user before delayed_deletion
1 file changed · +9 −0
glance/api/v1/images.py+9 −0 modified@@ -727,6 +727,15 @@ def delete(self, req, id): content_type="text/plain") image = self.get_image_meta_or_404(req, id) + + if not (req.context.is_admin + or image['owner'] == None + or image['owner'] == req.context.owner): + msg = _("Unable to delete image you do not own") + logger.debug(msg) + raise HTTPForbidden(msg, request=req, + content_type="text/plain") + if image['protected']: msg = _("Image is protected") logger.debug(msg)
90bcdc5a89e3Delete from store after registry delete.
4 files changed · +39 −6
glance/api/v1/images.py+11 −5 modified@@ -821,22 +821,28 @@ def delete(self, req, id): request=req, content_type="text/plain") - status = 'deleted' + if image['location'] and CONF.delayed_delete: + status = 'pending_delete' + else: + status = 'deleted' + try: + # Delete the image from the registry first, since we rely on it + # for authorization checks. + # See https://bugs.launchpad.net/glance/+bug/1065187 + registry.update_image_metadata(req.context, id, {'status': status}) + registry.delete_image_metadata(req.context, id) + # The image's location field may be None in the case # of a saving or queued image, therefore don't ask a backend # to delete the image if the backend doesn't yet store it. # See https://bugs.launchpad.net/glance/+bug/747799 if image['location']: if CONF.delayed_delete: - status = 'pending_delete' schedule_delayed_delete_from_backend(image['location'], id) else: safe_delete_from_backend(image['location'], req.context, id) - - registry.update_image_metadata(req.context, id, {'status': status}) - registry.delete_image_metadata(req.context, id) except exception.NotFound, e: msg = ("Failed to find image to delete: %(e)s" % locals()) for line in msg.split('\n'):
glance/tests/stubs.py+7 −1 modified@@ -60,7 +60,13 @@ def request(self, method, url, body=None, headers=None): def getresponse(self): mapper = routes.Mapper() - api = context.UnauthenticatedContextMiddleware(rserver.API(mapper)) + server = rserver.API(mapper) + # NOTE(markwash): we need to pass through context auth information if + # we have it. + if 'X-Auth-Token' in self.req.headers: + api = utils.FakeAuthMiddleware(server) + else: + api = context.UnauthenticatedContextMiddleware(server) webob_res = self.req.get_response(api) return utils.FakeHTTPResponse(status=webob_res.status_int,
glance/tests/unit/v1/test_api.py+20 −0 modified@@ -2930,6 +2930,26 @@ def test_delete_non_exists_image(self): res = req.get_response(self.api) self.assertEquals(res.status_int, webob.exc.HTTPNotFound.code) + def test_delete_not_allowed(self): + # Verify we can get the image data + req = webob.Request.blank("/images/%s" % UUID2) + req.method = 'GET' + req.headers['X-Auth-Token'] = 'user:tenant:' + res = req.get_response(self.api) + self.assertEqual(res.status_int, 200) + self.assertEqual(len(res.body), 19) + + # Verify we cannot delete the image + req.method = 'DELETE' + res = req.get_response(self.api) + self.assertEqual(res.status_int, 403) + + # Verify the image data is still there + req.method = 'GET' + res = req.get_response(self.api) + self.assertEqual(res.status_int, 200) + self.assertEqual(len(res.body), 19) + def test_delete_queued_image(self): """Delete an image in a queued state
glance/tests/utils.py+1 −0 modified@@ -368,6 +368,7 @@ def process_request(self, req): 'tenant': tenant, 'roles': roles, 'is_admin': self.is_admin, + 'auth_tok': auth_tok, } req.context = context.RequestContext(**kwargs)
6ab0992e5472Delete from store after registry delete.
4 files changed · +39 −6
glance/api/v1/images.py+11 −5 modified@@ -827,22 +827,28 @@ def delete(self, req, id): raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain") - status = 'deleted' + if image['location'] and CONF.delayed_delete: + status = 'pending_delete' + else: + status = 'deleted' + try: + # Delete the image from the registry first, since we rely on it + # for authorization checks. + # See https://bugs.launchpad.net/glance/+bug/1065187 + registry.update_image_metadata(req.context, id, {'status': status}) + registry.delete_image_metadata(req.context, id) + # The image's location field may be None in the case # of a saving or queued image, therefore don't ask a backend # to delete the image if the backend doesn't yet store it. # See https://bugs.launchpad.net/glance/+bug/747799 if image['location']: if CONF.delayed_delete: - status = 'pending_delete' schedule_delayed_delete_from_backend(image['location'], id) else: safe_delete_from_backend(image['location'], req.context, id) - - registry.update_image_metadata(req.context, id, {'status': status}) - registry.delete_image_metadata(req.context, id) except exception.NotFound, e: msg = ("Failed to find image to delete: %(e)s" % locals()) for line in msg.split('\n'):
glance/tests/stubs.py+7 −1 modified@@ -60,7 +60,13 @@ def request(self, method, url, body=None, headers=None): def getresponse(self): mapper = routes.Mapper() - api = context.UnauthenticatedContextMiddleware(rserver.API(mapper)) + server = rserver.API(mapper) + # NOTE(markwash): we need to pass through context auth information if + # we have it. + if 'X-Auth-Token' in self.req.headers: + api = utils.FakeAuthMiddleware(server) + else: + api = context.UnauthenticatedContextMiddleware(server) webob_res = self.req.get_response(api) return utils.FakeHTTPResponse(status=webob_res.status_int,
glance/tests/unit/v1/test_api.py+20 −0 modified@@ -3015,6 +3015,26 @@ def test_delete_non_exists_image(self): res = req.get_response(self.api) self.assertEquals(res.status_int, webob.exc.HTTPNotFound.code) + def test_delete_not_allowed(self): + # Verify we can get the image data + req = webob.Request.blank("/images/%s" % UUID2) + req.method = 'GET' + req.headers['X-Auth-Token'] = 'user:tenant:' + res = req.get_response(self.api) + self.assertEqual(res.status_int, 200) + self.assertEqual(len(res.body), 19) + + # Verify we cannot delete the image + req.method = 'DELETE' + res = req.get_response(self.api) + self.assertEqual(res.status_int, 403) + + # Verify the image data is still there + req.method = 'GET' + res = req.get_response(self.api) + self.assertEqual(res.status_int, 200) + self.assertEqual(len(res.body), 19) + def test_delete_queued_image(self): """Delete an image in a queued state
glance/tests/utils.py+1 −0 modified@@ -372,6 +372,7 @@ def process_request(self, req): 'tenant': tenant, 'roles': roles, 'is_admin': self.is_admin, + 'auth_tok': auth_tok, } req.context = context.RequestContext(**kwargs)
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
20- github.com/openstack/glance/commit/efd7e75b1f419a52c7103c7840e24af8e5deb29dnvdPatchWEB
- secunia.com/advisories/51174nvdVendor AdvisoryWEB
- secunia.com/advisories/51234nvdVendor AdvisoryWEB
- github.com/advisories/GHSA-6rrm-xxvh-7r87ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2012-4573ghsaADVISORY
- lists.fedoraproject.org/pipermail/package-announce/2012-November/092192.htmlnvdWEB
- lists.opensuse.org/opensuse-security-announce/2012-11/msg00002.htmlnvdWEB
- osvdb.org/87248nvdWEB
- packetstormsecurity.com/files/118733/Red-Hat-Security-Advisory-2012-1558-01.htmlnvdWEB
- rhn.redhat.com/errata/RHSA-2012-1558.htmlnvdWEB
- www.openwall.com/lists/oss-security/2012/11/07/6nvdWEB
- www.openwall.com/lists/oss-security/2012/11/09/5nvdWEB
- www.securityfocus.com/bid/56437nvdWEB
- www.ubuntu.com/usn/USN-1626-1nvdWEB
- www.ubuntu.com/usn/USN-1626-2nvdWEB
- bugs.launchpad.net/glance/+bug/1065187nvdWEB
- exchange.xforce.ibmcloud.com/vulnerabilities/79895nvdWEB
- github.com/openstack/glance/commit/6ab0992e5472ae3f9bef0d2ced41030655d9d2bcnvdWEB
- github.com/openstack/glance/commit/90bcdc5a89e350a358cf320a03f5afe99795f6f6nvdWEB
- github.com/pypa/advisory-database/tree/main/vulns/glance/PYSEC-2012-29.yamlghsaWEB
News mentions
0No linked articles in our index yet.