From c3e58bd943ccb4e1457914c3c2b5366bd0afee5a Mon Sep 17 00:00:00 2001 From: Stuart McLaren Date: Fri, 26 Jul 2013 15:55:47 +0000 Subject: [PATCH] Add v1 API x-image-meta- header whitelist Add a whitelist of allowed 'x-image-meta-xxx' style headers. Attempts to supply other, unexpected headers will return 400. This prevents cases such as 'x-image-meta-locations' being processed, which were not being handled correctly. Addresses bug 1205018. Change-Id: I771bb6ae2a4f9cbd7726f952c7a71da99162b490 --- glance/common/utils.py | 15 +++++++++++++++ glance/tests/unit/common/test_utils.py | 16 ++++++++++++++-- glance/tests/unit/common/test_wsgi.py | 2 -- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/glance/common/utils.py b/glance/common/utils.py index 28c72afe2d..d8c4dd6e6a 100644 --- a/glance/common/utils.py +++ b/glance/common/utils.py @@ -49,6 +49,18 @@ LOG = logging.getLogger(__name__) FEATURE_BLACKLIST = ['content-length', 'content-type', 'x-image-meta-size'] +# Whitelist of v1 API headers of form x-image-meta-xxx +IMAGE_META_HEADERS = ['x-image-meta-location', 'x-image-meta-size', + 'x-image-meta-is_public', 'x-image-meta-disk_format', + 'x-image-meta-container_format', 'x-image-meta-name', + 'x-image-meta-status', 'x-image-meta-copy_from', + 'x-image-meta-uri', 'x-image-meta-checksum', + 'x-image-meta-created_at', 'x-image-meta-updated_at', + 'x-image-meta-deleted-at', 'x-image-meta-min_ram', + 'x-image-meta-min_disk', 'x-image-meta-owner', + 'x-image-meta-store', 'x-image-meta-id', + 'x-image-meta-protected', 'x-image-meta-deleted'] + GLANCE_TEST_SOCKET_FD_STR = 'GLANCE_TEST_SOCKET_FD' @@ -237,6 +249,9 @@ def get_image_meta_from_headers(response): properties[field_name] = value or None elif key.startswith('x-image-meta-'): field_name = key[len('x-image-meta-'):].replace('-', '_') + if 'x-image-meta-' + field_name not in IMAGE_META_HEADERS: + msg = _(("Bad header: %s") % key) + raise exc.HTTPBadRequest(msg, content_type="text/plain") result[field_name] = value or None result['properties'] = properties if 'size' in result: diff --git a/glance/tests/unit/common/test_utils.py b/glance/tests/unit/common/test_utils.py index 3db4dc272a..23c3858d02 100644 --- a/glance/tests/unit/common/test_utils.py +++ b/glance/tests/unit/common/test_utils.py @@ -120,9 +120,21 @@ class TestUtils(test_utils.BaseTestCase): def test_get_meta_from_headers(self): resp = webob.Response() - resp.headers = {"x-image-meta-*": 'test'} + resp.headers = {"x-image-meta-name": 'test'} result = utils.get_image_meta_from_headers(resp) - self.assertEqual({'*': 'test', 'properties': {}}, result) + self.assertEqual({'name': 'test', 'properties': {}}, result) + + def test_get_meta_from_headers_bad_headers(self): + resp = webob.Response() + resp.headers = {"x-image-meta-bad": 'test'} + self.assertRaises(webob.exc.HTTPBadRequest, + utils.get_image_meta_from_headers, resp) + resp.headers = {"x-image-meta-": 'test'} + self.assertRaises(webob.exc.HTTPBadRequest, + utils.get_image_meta_from_headers, resp) + resp.headers = {"x-image-meta-*": 'test'} + self.assertRaises(webob.exc.HTTPBadRequest, + utils.get_image_meta_from_headers, resp) def test_add_features_to_http_headers(self): features_test1 = {'x-image-meta-size': 'test'} diff --git a/glance/tests/unit/common/test_wsgi.py b/glance/tests/unit/common/test_wsgi.py index fbfd0a42e1..be453e050e 100644 --- a/glance/tests/unit/common/test_wsgi.py +++ b/glance/tests/unit/common/test_wsgi.py @@ -270,7 +270,6 @@ class TestHelpers(test_utils.BaseTestCase): """ fixture = {'name': 'fake public image', 'is_public': True, - 'type': 'kernel', 'size': 19, 'location': "file:///tmp/glance-tests/2", 'properties': {'distro': 'Ubuntu 10.04 LTS'}} @@ -285,7 +284,6 @@ class TestHelpers(test_utils.BaseTestCase): fixture = {'name': 'fake public image', 'is_public': True, 'deleted': False, - 'type': 'kernel', 'name': None, 'size': 19, 'location': "file:///tmp/glance-tests/2",