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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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