From aa2a84ba8a8d6ba08141492502b3872ad0d81c2d Mon Sep 17 00:00:00 2001 From: Rebecca Finn Date: Wed, 13 Jul 2016 19:09:39 +0000 Subject: [PATCH] Check object metadata constraints after authorizing In the object proxy controller, the POST method checked the metadata of an object before calling swift.authorize. This could allow an auth middleware to set metadata that violates constraints. Instead, checking the metadata should take place after authorization. Change-Id: I5f05039498c406473952e78c6a40ec11e8b53f8e Closes-Bug: #1596944 --- swift/proxy/controllers/obj.py | 6 +++--- test/unit/proxy/test_server.py | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/swift/proxy/controllers/obj.py b/swift/proxy/controllers/obj.py index a948bbb6d2..be9c2bf472 100644 --- a/swift/proxy/controllers/obj.py +++ b/swift/proxy/controllers/obj.py @@ -212,9 +212,6 @@ class BaseObjectController(Controller): @delay_denial def POST(self, req): """HTTP POST request handler.""" - error_response = check_metadata(req, 'object') - if error_response: - return error_response container_info = self.container_info( self.account_name, self.container_name, req) container_partition = container_info['partition'] @@ -226,6 +223,9 @@ class BaseObjectController(Controller): return aresp if not containers: return HTTPNotFound(request=req) + error_response = check_metadata(req, 'object') + if error_response: + return error_response req, delete_at_container, delete_at_part, \ delete_at_nodes = self._config_obj_expiration(req) diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py index 44a23ef6f4..bea71a4c12 100644 --- a/test/unit/proxy/test_server.py +++ b/test/unit/proxy/test_server.py @@ -3418,6 +3418,25 @@ class TestObjectController(unittest.TestCase): res = req.get_response(self.app) self.assertEqual(res.status_int, 400) + def test_POST_meta_authorize(self): + def authorize(req): + req.headers['X-Object-Meta-Foo'] = 'x' * (limit + 1) + return + with save_globals(): + limit = constraints.MAX_META_VALUE_LENGTH + self.app.object_post_as_copy = False + controller = ReplicatedObjectController( + self.app, 'account', 'container', 'object') + set_http_connect(200, 200, 202, 202, 202) + # acct cont obj obj obj + req = Request.blank('/v1/a/c/o', {'REQUEST_METHOD': 'POST'}, + headers={'Content-Type': 'foo/bar', + 'X-Object-Meta-Foo': 'x'}) + req.environ['swift.authorize'] = authorize + self.app.update_request(req) + res = controller.POST(req) + self.assertEqual(res.status_int, 400) + def test_POST_meta_key_len(self): with save_globals(): limit = constraints.MAX_META_NAME_LENGTH