Moderate severityNVD Advisory· Published Nov 11, 2012· Updated Apr 29, 2026
CVE-2012-5482
CVE-2012-5482
Description
The v2 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. NOTE: this vulnerability exists because of an incomplete fix for CVE-2012-4573.
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
2fc0ee7623ec5Ensure authorization before deleting from store
2 files changed · +24 −9
glance/api/v2/images.py+12 −9 modified@@ -268,19 +268,22 @@ def delete(self, req, image_id): % locals()) raise webob.exc.HTTPForbidden(explanation=msg) - status = 'deleted' - if image['location']: - if CONF.delayed_delete: - status = 'pending_delete' - self.store_api.schedule_delayed_delete_from_backend( - image['location'], id) - else: - self.store_api.safe_delete_from_backend(image['location'], - req.context, id) + if image['location'] and CONF.delayed_delete: + status = 'pending_delete' + else: + status = 'deleted' try: self.db_api.image_update(req.context, image_id, {'status': status}) self.db_api.image_destroy(req.context, image_id) + + if image['location']: + if CONF.delayed_delete: + self.store_api.schedule_delayed_delete_from_backend( + image['location'], id) + else: + self.store_api.safe_delete_from_backend(image['location'], + req.context, id) except (exception.NotFound, exception.Forbidden): msg = ("Failed to find image %(image_id)s to delete" % locals()) LOG.info(msg)
glance/tests/functional/v2/test_images.py+12 −0 modified@@ -218,6 +218,12 @@ def test_permissions(self): self.assertEqual(201, response.status_code) image_id = json.loads(response.text)['id'] + # Upload some image data + path = self._url('/v2/images/%s/file' % image_id) + headers = self._headers({'Content-Type': 'application/octet-stream'}) + response = requests.put(path, headers=headers, data='ZZZZZ') + self.assertEqual(201, response.status_code) + # TENANT1 should see the image in their list path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) @@ -300,6 +306,12 @@ def test_permissions(self): response = requests.delete(path, headers=headers) self.assertEqual(404, response.status_code) + # Image data should still be present after the failed delete + path = self._url('/v2/images/%s/file' % image_id) + response = requests.get(path, headers=self._headers()) + self.assertEqual(200, response.status_code) + self.assertEqual(response.text, 'ZZZZZ') + self.stop_servers() def test_tag_lifecycle(self):
b591304b8980Ensure authorization before deleting from store
2 files changed · +24 −9
glance/api/v2/images.py+12 −9 modified@@ -260,19 +260,22 @@ def delete(self, req, image_id): % locals()) raise webob.exc.HTTPForbidden(explanation=msg) - status = 'deleted' - if image['location']: - if CONF.delayed_delete: - status = 'pending_delete' - self.store_api.schedule_delayed_delete_from_backend( - image['location'], id) - else: - self.store_api.safe_delete_from_backend(image['location'], - req.context, id) + if image['location'] and CONF.delayed_delete: + status = 'pending_delete' + else: + status = 'deleted' try: self.db_api.image_update(req.context, image_id, {'status': status}) self.db_api.image_destroy(req.context, image_id) + + if image['location']: + if CONF.delayed_delete: + self.store_api.schedule_delayed_delete_from_backend( + image['location'], id) + else: + self.store_api.safe_delete_from_backend(image['location'], + req.context, id) except (exception.NotFound, exception.Forbidden): msg = ("Failed to find image %(image_id)s to delete" % locals()) LOG.info(msg)
glance/tests/functional/v2/test_images.py+12 −0 modified@@ -218,6 +218,12 @@ def test_permissions(self): self.assertEqual(201, response.status_code) image_id = json.loads(response.text)['id'] + # Upload some image data + path = self._url('/v2/images/%s/file' % image_id) + headers = self._headers({'Content-Type': 'application/octet-stream'}) + response = requests.put(path, headers=headers, data='ZZZZZ') + self.assertEqual(201, response.status_code) + # TENANT1 should see the image in their list path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) @@ -300,6 +306,12 @@ def test_permissions(self): response = requests.delete(path, headers=headers) self.assertEqual(404, response.status_code) + # Image data should still be present after the failed delete + path = self._url('/v2/images/%s/file' % image_id) + response = requests.get(path, headers=self._headers()) + self.assertEqual(200, response.status_code) + self.assertEqual(response.text, 'ZZZZZ') + self.stop_servers() def test_tag_lifecycle(self):
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
16- secunia.com/advisories/51174nvdVendor AdvisoryWEB
- github.com/advisories/GHSA-vwr9-9f8v-vp5mghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2012-5482ghsaADVISORY
- lists.fedoraproject.org/pipermail/package-announce/2012-November/092192.htmlnvdWEB
- lists.opensuse.org/opensuse-security-announce/2012-11/msg00002.htmlnvdWEB
- osvdb.org/87248nvdWEB
- www.openwall.com/lists/oss-security/2012/11/07/6nvdWEB
- www.openwall.com/lists/oss-security/2012/11/08/2nvdWEB
- www.openwall.com/lists/oss-security/2012/11/09/1nvdWEB
- www.openwall.com/lists/oss-security/2012/11/09/5nvdWEB
- www.securityfocus.com/bid/56437nvdWEB
- bugs.launchpad.net/glance/+bug/1076506nvdWEB
- exchange.xforce.ibmcloud.com/vulnerabilities/80019nvdWEB
- github.com/openstack/glance/commit/b591304b8980d8aca8fa6cda9ea1621aca000c88nvdWEB
- github.com/openstack/glance/commit/fc0ee7623ec59c87ac6fc671e95a9798d6f2e2c3nvdWEB
- github.com/pypa/advisory-database/tree/main/vulns/glance/PYSEC-2012-30.yamlghsaWEB
News mentions
0No linked articles in our index yet.