From 354bbed18bd4569c6e2c7557478095072fc55903 Mon Sep 17 00:00:00 2001 From: Jason Del Ponte Date: Thu, 14 Apr 2016 16:04:46 -0700 Subject: [PATCH] private/signer/v4: Resign requests which are too old Requests that are delayed to be sent, or are retried so many times that the original date the request was signed with is past the age a signature can be, the request needs to be resigned. This prevents issues for request being retried many times, and finally succeding but encounter an expired signature. Fix #486 --- private/signer/v4/v4.go | 6 ++++-- private/signer/v4/v4_test.go | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/private/signer/v4/v4.go b/private/signer/v4/v4.go index 5a434b3bbb5..eb237312121 100644 --- a/private/signer/v4/v4.go +++ b/private/signer/v4/v4.go @@ -153,6 +153,7 @@ func Sign(req *request.Request) { } req.Error = s.sign() + req.Time = s.Time req.SignedHeaderVals = s.signedHeaderVals } @@ -162,11 +163,12 @@ func (v4 *signer) sign() error { } if v4.isRequestSigned() { - if !v4.Credentials.IsExpired() { + if !v4.Credentials.IsExpired() && time.Now().Before(v4.Time.Add(10*time.Minute)) { // If the request is already signed, and the credentials have not - // expired yet ignore the signing request. + // expired, and the request is not too old ignore the signing request. return nil } + v4.Time = time.Now() // The credentials have expired for this request. The current signing // is invalid, and needs to be request because the request will fail. diff --git a/private/signer/v4/v4_test.go b/private/signer/v4/v4_test.go index 309da8ed6bc..c22e5ff38d8 100644 --- a/private/signer/v4/v4_test.go +++ b/private/signer/v4/v4_test.go @@ -267,6 +267,29 @@ func TestPreResignRequestExpiredCreds(t *testing.T) { assert.NotContains(t, signedHeaders, "x-amz-signedHeaders") } +func TestResignRequestExpiredRequest(t *testing.T) { + creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION") + svc := awstesting.NewClient(&aws.Config{Credentials: creds}) + r := svc.NewRequest( + &request.Operation{ + Name: "BatchGetItem", + HTTPMethod: "POST", + HTTPPath: "/", + }, + nil, + nil, + ) + + Sign(r) + querySig := r.HTTPRequest.Header.Get("Authorization") + + // Simulate the request occured 15 minutes in the past + r.Time = r.Time.Add(-15 * time.Minute) + + Sign(r) + assert.NotEqual(t, querySig, r.HTTPRequest.Header.Get("Authorization")) +} + func BenchmarkPresignRequest(b *testing.B) { signer := buildSigner("dynamodb", "us-east-1", time.Now(), 300*time.Second, "{}") for i := 0; i < b.N; i++ {