From ea006b13a7ad5229a3dcdbba0e7aef438e873b6c Mon Sep 17 00:00:00 2001 From: Yikun Jiang Date: Wed, 31 Jan 2018 10:50:46 +0800 Subject: [PATCH] [Placement] Invalid query parameter could lead to HTTP 500 Invalid query parameter could lead to HTTP 500, although Placement used JSON Schema verification to check input query params, but query like: GET allocation_candidates?limit=%88 will still lead to HTTP 500, as it failed to parse at webob which is pre JSON Schema check. Change-Id: Iba8d29cb442c610de53e70c81533a8e1243d12dc Partial-bug: #1746202 --- nova/api/openstack/placement/util.py | 4 +++- .../unit/api/openstack/placement/test_util.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/placement/util.py b/nova/api/openstack/placement/util.py index 30961cd10a89..cae3f0ecb313 100644 --- a/nova/api/openstack/placement/util.py +++ b/nova/api/openstack/placement/util.py @@ -201,9 +201,11 @@ def trait_url(environ, trait): def validate_query_params(req, schema): try: + # NOTE(Kevin_Zheng): The webob package throws UnicodeError when + # param cannot be decoded. Catch this and raise HTTP 400. jsonschema.validate(dict(req.GET), schema, format_checker=jsonschema.FormatChecker()) - except jsonschema.ValidationError as exc: + except (jsonschema.ValidationError, UnicodeDecodeError) as exc: raise webob.exc.HTTPBadRequest( _('Invalid query string parameters: %(exc)s') % {'exc': exc}) diff --git a/nova/tests/unit/api/openstack/placement/test_util.py b/nova/tests/unit/api/openstack/placement/test_util.py index c7b7cb4e5948..0dea037bb231 100644 --- a/nova/tests/unit/api/openstack/placement/test_util.py +++ b/nova/tests/unit/api/openstack/placement/test_util.py @@ -21,6 +21,7 @@ from oslo_middleware import request_id from oslo_utils import timeutils import webob +import six import six.moves.urllib.parse as urlparse from nova.api.openstack.placement import lib as pl @@ -146,6 +147,22 @@ class TestExtractJSON(test.NoDBTestCase): self.assertEqual(uuidsentinel.rp_uuid, data['uuid']) +class QueryParamsSchemaTestCase(test.NoDBTestCase): + + def test_validate_request(self): + schema = { + 'type': 'object', + 'properties': { + 'foo': {'type': 'string'} + }, + 'additionalProperties': False} + req = webob.Request.blank('/test?foo=%88') + error = self.assertRaises(webob.exc.HTTPBadRequest, + util.validate_query_params, + req, schema) + self.assertIn('Invalid query string parameters', six.text_type(error)) + + class TestJSONErrorFormatter(test.NoDBTestCase): def setUp(self):