VYPR
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.

PackageAffected versionsPatched versions
glancePyPI
< 11.0.0a011.0.0a0

Affected products

3

Patches

2
fc0ee7623ec5

Ensure authorization before deleting from store

https://github.com/openstack/glanceMark J. WashenbergerNov 8, 2012via ghsa
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):
    
b591304b8980

Ensure authorization before deleting from store

https://github.com/openstack/glanceMark J. WashenbergerNov 8, 2012via ghsa
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

News mentions

0

No linked articles in our index yet.