From b555c92940a8bf636a1b4370b41808485513b0d7 Mon Sep 17 00:00:00 2001 From: Ben McClelland Date: Wed, 13 Mar 2024 22:48:24 -0700 Subject: [PATCH] fix: include all request signed headers in signature canonical string Fixes #457. There are some buggy clients that include headers not actually set on the request in the signed headers list. For these we need to include them in the signature canoncal string with empty values. --- s3api/utils/auth_test.go | 2 +- s3api/utils/utils.go | 7 +++++++ s3api/utils/utils_test.go | 5 ++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/s3api/utils/auth_test.go b/s3api/utils/auth_test.go index d8cdee3f..f25c2c12 100644 --- a/s3api/utils/auth_test.go +++ b/s3api/utils/auth_test.go @@ -84,7 +84,7 @@ func Test_Client_UserAgent(t *testing.T) { } req.Host = host - req.Header.Add("X-Amz-Content-Sha256", zeroLenSig) + req.Header.Set("X-Amz-Content-Sha256", zeroLenSig) signer := v4.NewSigner() diff --git a/s3api/utils/utils.go b/s3api/utils/utils.go index aa4346bb..f926bf3a 100644 --- a/s3api/utils/utils.go +++ b/s3api/utils/utils.go @@ -73,6 +73,13 @@ func createHttpRequestFromCtx(ctx *fiber.Ctx, signedHdrs []string, contentLength } }) + // make sure all headers in the signed headers are present + for _, header := range signedHdrs { + if httpReq.Header.Get(header) == "" { + httpReq.Header.Set(header, "") + } + } + // Check if Content-Length in signed headers // If content length is non 0, then the header will be included if !includeHeader("Content-Length", signedHdrs) { diff --git a/s3api/utils/utils_test.go b/s3api/utils/utils_test.go index a2c9ac01..5d8ef5f2 100644 --- a/s3api/utils/utils_test.go +++ b/s3api/utils/utils_test.go @@ -35,6 +35,7 @@ func TestCreateHttpRequestFromCtx(t *testing.T) { args args want *http.Request wantErr bool + hdrs []string }{ { name: "Success-response", @@ -43,6 +44,7 @@ func TestCreateHttpRequestFromCtx(t *testing.T) { }, want: request, wantErr: false, + hdrs: []string{}, }, { name: "Success-response-With-Headers", @@ -51,11 +53,12 @@ func TestCreateHttpRequestFromCtx(t *testing.T) { }, want: request2, wantErr: false, + hdrs: []string{"X-Amz-Mfa"}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := createHttpRequestFromCtx(tt.args.ctx, []string{"X-Amz-Mfa"}, 0) + got, err := createHttpRequestFromCtx(tt.args.ctx, tt.hdrs, 0) if (err != nil) != tt.wantErr { t.Errorf("CreateHttpRequestFromCtx() error = %v, wantErr %v", err, tt.wantErr) return