From 51b829338a399b02a696a9925f9a36a5b5078d2c Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 5 Dec 2023 14:40:54 -0800 Subject: [PATCH] Preserve user provided http headers in aws.sign_req Currently while all the headers are signed the headers in the returned object are missing all the original user provided headers This means that if you pass the object directly to http.send amazon will fail the request because the signed data doesn't match the canonical request. Users can work around it by using object.union to restore the original headers, but would be nice to avoid that extra step Signed-off-by: Peter --- .../testdata/providers-aws/aws-sign_req.yaml | 3 ++- topdown/providers.go | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/test/cases/testdata/providers-aws/aws-sign_req.yaml b/test/cases/testdata/providers-aws/aws-sign_req.yaml index 3979196b1d..a8bab4222f 100644 --- a/test/cases/testdata/providers-aws/aws-sign_req.yaml +++ b/test/cases/testdata/providers-aws/aws-sign_req.yaml @@ -43,7 +43,8 @@ cases: "Authorization": "AWS4-HMAC-SHA256 Credential=MYAWSACCESSKEYGOESHERE/20151228/us-east-1/s3/aws4_request,SignedHeaders=foo;host;x-amz-content-sha256;x-amz-date,Signature=8f1dc7c9b9978356a0d0989fd26a95307f4f8a4aa264d8220647b7097d839952", "host": "example.com", "x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "x-amz-date": "20151228T140825Z" + "x-amz-date": "20151228T140825Z", + "foo": "bar" }, "method": "get", "url": "http://example.com" diff --git a/topdown/providers.go b/topdown/providers.go index 0b9e012268..113281b0f9 100644 --- a/topdown/providers.go +++ b/topdown/providers.go @@ -172,10 +172,21 @@ func builtinAWSSigV4SignReq(ctx BuiltinContext, operands []*ast.Term, iter func( } // Sign the request object's headers, and reconstruct the headers map. - authHeader, signedHeadersMap := aws.SignV4(objectToMap(headers), method, theURL, body, service, awsCreds, signingTimestamp) + headersMap := objectToMap(headers) + authHeader, awsHeadersMap := aws.SignV4(headersMap, method, theURL, body, service, awsCreds, signingTimestamp) signedHeadersObj := ast.NewObject() + // Restore original headers + for k, v := range headersMap { + // objectToMap doesn't support arrays + if len(v) == 1 { + signedHeadersObj.Insert(ast.StringTerm(k), ast.StringTerm(v[0])) + } + } + // Set authorization header signedHeadersObj.Insert(ast.StringTerm("Authorization"), ast.StringTerm(authHeader)) - for k, v := range signedHeadersMap { + + // set aws signature headers + for k, v := range awsHeadersMap { signedHeadersObj.Insert(ast.StringTerm(k), ast.StringTerm(v)) }