Skip to content

With aws-sdk-go-v2 v1.24.1 version requests to the Presingned URL fails with SignatureDoesNotMatch error #2483

Closed
@cristiangb13

Description

@cristiangb13

Describe the bug

When upgrading to github.com/aws/aws-sdk-go-v2 v1.24.1 I am getting a SignatureDoesNotMatch error when doing a PUT on a presigned url.

Expected Behavior

No errors when PUT request to presingned url

Current Behavior

When I make the PUT request to the presigned url this is the error:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>SignatureDoesNotMatch</Code>
    <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
    <AWSAccessKeyId>[REDACTED]</AWSAccessKeyId>
    <StringToSign>[REDACTED]</StringToSign>
    <SignatureProvided>[REDACTED]</SignatureProvided>
    <StringToSignBytes>[REDACTED]</StringToSignBytes>
    <CanonicalRequest>PUT [REDACTED]</CanonicalRequest>
    <CanonicalRequestBytes>[REDACTED]</CanonicalRequestBytes>
    <RequestId>[REDACTED]</RequestId>
    <HostId>[REDACTED]</HostId>
</Error>

Reproduction Steps

Generate presigned URL:

func (p Presigner) PutObject(
	ctx context.Context,
	objectKey string,
	lifetimeSecs int64,
) (*v4.PresignedHTTPRequest, error) {
	return p.PresignClient.PresignPutObject(
		ctx,
		&s3.PutObjectInput{
			Bucket: aws.String(string(p.BucketName)),
			Key:    aws.String(objectKey),
		},
		s3.WithPresignExpires(time.Duration(lifetimeSecs*int64(time.Second))),
	)
}

Make a request to the presigned URL generated.

Possible Solution

I have been debugging and I think the error is introduced in this commit.

Now when the presigned url is generated it goes through this middleware github.com/aws/[email protected]/aws/retry/middleware.go:286 that adds this header Amz-Sdk-Request:

const retryMetricHeader = "Amz-Sdk-Request"

switch req := in.Request.(type) {
	case *http.Request:
		req.Header[retryMetricHeader] = append(req.Header[retryMetricHeader][:0], strings.Join(parts, "; "))
	default:
		return out, metadata, fmt.Errorf("unknown transport type %T", req)
	}

And this causes the url to be generated with this &X-Amz-SignedHeaders=amz-sdk-request;host in aws/[email protected]/aws/signer/v4/v4.go:185 on signedHeadersStr = amz-sdk-request;host

signedHeaders, signedHeadersStr, canonicalHeaderStr := s.buildCanonicalHeaders(host, v4Internal.IgnoredHeaders, unsignedHeaders, s.Request.ContentLength)

With github.com/aws/aws-sdk-go-v2 v1.24.0 signedHeadersStr = host

If I exclude the header Amz-Sdk-Request at github.com/aws/[email protected]/aws/signer/internal/v4/headers.go:4

// IgnoredHeaders is a list of headers that are ignored during signing
var IgnoredHeaders = Rules{
	ExcludeList{
		MapRule{
			"Authorization":   struct{}{},
			"User-Agent":      struct{}{},
			"X-Amzn-Trace-Id": struct{}{},
			"Expect":          struct{}{},
			"Amz-Sdk-Request": struct{}{},
		},
	},
}

The url is generated correctly and works.

I don't have much context and I don't know if the solution is to simply add the header to IgnoredHeaders or if it shouldn't go through that Middleware.

Additional Information/Context

No response

AWS Go SDK V2 Module Versions Used

github.com/aws/aws-sdk-go-v2 v1.24.1

Compiler and Version used

go version go1.21.1 darwin/arm64

Operating System and version

macOS Ventura 13.4

Metadata

Metadata

Assignees

Labels

bugThis issue is a bug.p2This is a standard priority issueresponse-requestedWaiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions