diff --git a/.changelog/d6a8aa444ebf496e8554e58655c3b281.json b/.changelog/d6a8aa444ebf496e8554e58655c3b281.json new file mode 100644 index 00000000000..1f68ce277f0 --- /dev/null +++ b/.changelog/d6a8aa444ebf496e8554e58655c3b281.json @@ -0,0 +1,8 @@ +{ + "id": "d6a8aa44-4ebf-496e-8554-e58655c3b281", + "type": "bugfix", + "description": "Re-enable hoisting of `X-Amz-Expected-Bucket-Owner` in presigning, but in lowercase form, such that it is correctly enforced.", + "modules": [ + "." + ] +} \ No newline at end of file diff --git a/aws/signer/internal/v4/headers.go b/aws/signer/internal/v4/headers.go index ca738f234b3..71b1a352171 100644 --- a/aws/signer/internal/v4/headers.go +++ b/aws/signer/internal/v4/headers.go @@ -38,7 +38,6 @@ var RequiredSignedHeaders = Rules{ "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{}, "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{}, "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, - "X-Amz-Expected-Bucket-Owner": struct{}{}, "X-Amz-Grant-Full-control": struct{}{}, "X-Amz-Grant-Read": struct{}{}, "X-Amz-Grant-Read-Acp": struct{}{}, diff --git a/aws/signer/v4/v4.go b/aws/signer/v4/v4.go index 55dfd07ba87..dcd896a9bf6 100644 --- a/aws/signer/v4/v4.go +++ b/aws/signer/v4/v4.go @@ -395,6 +395,12 @@ func buildQuery(r v4Internal.Rule, header http.Header) (url.Values, http.Header) query := url.Values{} unsignedHeaders := http.Header{} for k, h := range header { + // literally just this header has this constraint for some stupid reason, + // see #2508 + if k == "X-Amz-Expected-Bucket-Owner" { + k = "x-amz-expected-bucket-owner" + } + if r.IsValid(k) { query[k] = h } else {