diff --git a/swift/common/middleware/crypto/decrypter.py b/swift/common/middleware/crypto/decrypter.py index 3431e4efc6..7caa34aee6 100644 --- a/swift/common/middleware/crypto/decrypter.py +++ b/swift/common/middleware/crypto/decrypter.py @@ -16,7 +16,7 @@ import base64 import json -from swift.common.constraints import valid_api_version +from swift.common.constraints import valid_api_version, check_utf8 from swift.common.header_key_dict import HeaderKeyDict from swift.common.http import is_success from swift.common.middleware.crypto.crypto_utils import CryptoWSGIContext, \ @@ -26,7 +26,7 @@ from swift.common.request_helpers import get_object_transient_sysmeta, \ get_sys_meta_prefix, get_user_meta_prefix, \ get_container_update_override_key from swift.common.swob import Request, HTTPException, \ - HTTPInternalServerError, wsgi_to_bytes, bytes_to_wsgi + HTTPInternalServerError, wsgi_to_bytes, bytes_to_wsgi, wsgi_to_str from swift.common.utils import get_logger, config_true_value, \ parse_content_range, closing_if_possible, parse_content_type, \ FileLikeIter, multipart_byteranges_to_document_iters @@ -461,6 +461,11 @@ class Decrypter(object): if not valid_api_version(parts[0]): # Not a swift request return self.app(env, start_response) + if not check_utf8(wsgi_to_str(req.path_info), + internal=req.allow_reserved_names): + # Not a valid swift request + return self.app(env, start_response) + # TODO any other invalid paths we want to ignore?? if parts[3] and req.method in ('GET', 'HEAD'): handler = DecrypterObjContext(self, self.logger).handle diff --git a/test/unit/common/middleware/crypto/test_decrypter.py b/test/unit/common/middleware/crypto/test_decrypter.py index 7f95fa9db6..1921bd5032 100644 --- a/test/unit/common/middleware/crypto/test_decrypter.py +++ b/test/unit/common/middleware/crypto/test_decrypter.py @@ -1223,6 +1223,18 @@ class TestDecrypter(unittest.TestCase): resp = req.get_response(app) self.assertEqual(resp.status_int, 404) + def test_invalid_swift_path(self): + path = '/v1/\xC0.\xC0./\xC0.\xC0./\xC0.\xC0./\xC0.\xC0./winnt/win.ini' + fake_swift = FakeSwift() + fake_swift.register('GET', path, HTTPNotFound, {}) + app = keymaster.KeyMaster(decrypter.Decrypter(fake_swift, {}), { + 'encryption_root_secret': 'A' * 80, + }) + app.app.logger = debug_logger() + req = Request.blank(path) + resp = req.get_response(app) + self.assertEqual(resp.status_int, 404) + if __name__ == '__main__': unittest.main()