Comply with AWS signature calculation (s3v4)
The current implementation of s3 signature calculation rely on WSGI Url encoding which is discouraged by AWS: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html. This leads to reject requests with valid signature. This update encode only characters specified by AWS except 'A'-'Z', 'a'-'z', '0'-'9', '-', '.', '_', and '~' to comply AWS signature calculation. Fixes LP Bug #1961841 Change-Id: Ifa8f94544224c3379e7f2805f6f86d0b0a47279a
This commit is contained in:
parent
014c98e853
commit
cb8b3cdab2
@ -401,7 +401,8 @@ class SigV4Mixin(object):
|
||||
"""
|
||||
It won't require bucket name in canonical_uri for v4.
|
||||
"""
|
||||
return swob.wsgi_to_bytes(self.environ.get('RAW_PATH_INFO', self.path))
|
||||
return swob.wsgi_to_bytes(swob.wsgi_quote(
|
||||
self.environ.get('PATH_INFO', self.path), safe='-_.~/'))
|
||||
|
||||
def _canonical_request(self):
|
||||
# prepare 'canonical_request'
|
||||
|
@ -898,6 +898,33 @@ class TestRequest(S3ApiTestCase):
|
||||
sigv4_req._canonical_request().endswith(b'UNSIGNED-PAYLOAD'))
|
||||
self.assertTrue(sigv4_req.check_signature('secret'))
|
||||
|
||||
@patch.object(S3Request, '_validate_dates', lambda *a: None)
|
||||
def test_check_signature_sigv4_url_encode(self):
|
||||
environ = {
|
||||
'HTTP_HOST': 'bucket.s3.test.com',
|
||||
'REQUEST_METHOD': 'PUT',
|
||||
'RAW_PATH_INFO': '/test/~/file,1_1:1-1'}
|
||||
headers = {
|
||||
'Authorization':
|
||||
'AWS4-HMAC-SHA256 '
|
||||
'Credential=test/20210104/us-east-1/s3/aws4_request, '
|
||||
'SignedHeaders=host;x-amz-content-sha256;x-amz-date,'
|
||||
'Signature=06559fbf839b7ceac19d69f510a2d3b7dcb569c8df310965cc1'
|
||||
'6a1dc55b3394a',
|
||||
'X-Amz-Content-SHA256': 'UNSIGNED-PAYLOAD',
|
||||
'Date': 'Mon, 04 Jan 2021 10:26:23 -0000',
|
||||
'X-Amz-Date': '20210104T102623Z'}
|
||||
|
||||
# Virtual hosted-style
|
||||
self.s3api.conf.storage_domain = 's3.test.com'
|
||||
req = Request.blank(
|
||||
environ['RAW_PATH_INFO'], environ=environ, headers=headers)
|
||||
sigv4_req = SigV4Request(req.environ)
|
||||
canonical_req = sigv4_req._canonical_request()
|
||||
self.assertIn(b'PUT\n/test/~/file%2C1_1%3A1-1\n', canonical_req)
|
||||
self.assertTrue(canonical_req.endswith(b'UNSIGNED-PAYLOAD'))
|
||||
self.assertTrue(sigv4_req.check_signature('secret'))
|
||||
|
||||
@patch.object(S3Request, '_validate_dates', lambda *a: None)
|
||||
def test_check_sigv4_req_zero_content_length_sha256(self):
|
||||
# Virtual hosted-style
|
||||
|
Loading…
x
Reference in New Issue
Block a user