From be8c07dcb635ca6c3f567d4173e95dad09a3efe5 Mon Sep 17 00:00:00 2001 From: Jason Del Ponte <961963+jasdel@users.noreply.github.com> Date: Fri, 18 Jun 2021 11:52:51 -0700 Subject: [PATCH] aws/signer/v4: Add X-Amz-Object-Lock-* as unhoisted presign headers (#3968) Updates the SigV4 signer to exclude the X-Amz-Object-Lock- group of headers to not be signed as a part of the query string for presigned URLs. Related to aws/aws-sdk-go-v2#1307 --- CHANGELOG_PENDING.md | 2 ++ aws/signer/v4/header_rules.go | 16 ++++++------- aws/signer/v4/header_rules_test.go | 8 +++---- aws/signer/v4/headers_test.go | 37 ++++++++++++++++++++++++++++++ aws/signer/v4/v4.go | 11 +++++---- 5 files changed, 57 insertions(+), 17 deletions(-) create mode 100644 aws/signer/v4/headers_test.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 85d47d2496c..d744081f6a6 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -3,5 +3,7 @@ ### SDK Enhancements ### SDK Bugs +* `aws/signer/v4`: Add X-Amz-Object-Lock-* as unhoisted presign headers + * Updates the SigV4 signer to exlucde the X-Amz-Object-Lock- group of headers to not be signed as a part of the query string for presigned URLs. * `private/protocol`: Add support for UTC offset for ISO8601 datetime formats ([#3960](https://github.com/aws/aws-sdk-go/pull/3960)) * Updates the SDK's parsing of ISO8601 date time formats to support UTC offsets. diff --git a/aws/signer/v4/header_rules.go b/aws/signer/v4/header_rules.go index 07ea799fbd3..716e6181f54 100644 --- a/aws/signer/v4/header_rules.go +++ b/aws/signer/v4/header_rules.go @@ -34,23 +34,23 @@ func (m mapRule) IsValid(value string) bool { return ok } -// whitelist is a generic rule for whitelisting -type whitelist struct { +// allowList is a generic rule for allow listing +type allowList struct { rule } -// IsValid for whitelist checks if the value is within the whitelist -func (w whitelist) IsValid(value string) bool { +// IsValid for allow list checks if the value is within the allow list +func (w allowList) IsValid(value string) bool { return w.rule.IsValid(value) } -// blacklist is a generic rule for blacklisting -type blacklist struct { +// excludeList is a generic rule for blacklisting +type excludeList struct { rule } -// IsValid for whitelist checks if the value is within the whitelist -func (b blacklist) IsValid(value string) bool { +// IsValid for allow list checks if the value is within the allow list +func (b excludeList) IsValid(value string) bool { return !b.rule.IsValid(value) } diff --git a/aws/signer/v4/header_rules_test.go b/aws/signer/v4/header_rules_test.go index f4be951acac..856dde9546e 100644 --- a/aws/signer/v4/header_rules_test.go +++ b/aws/signer/v4/header_rules_test.go @@ -5,7 +5,7 @@ import ( ) func TestRuleCheckWhitelist(t *testing.T) { - w := whitelist{ + w := allowList{ mapRule{ "Cache-Control": struct{}{}, }, @@ -20,7 +20,7 @@ func TestRuleCheckWhitelist(t *testing.T) { } func TestRuleCheckBlacklist(t *testing.T) { - b := blacklist{ + b := excludeList{ mapRule{ "Cache-Control": struct{}{}, }, @@ -50,7 +50,7 @@ func TestRuleCheckPattern(t *testing.T) { func TestRuleComplexWhitelist(t *testing.T) { w := rules{ - whitelist{ + allowList{ mapRule{ "Cache-Control": struct{}{}, }, @@ -59,7 +59,7 @@ func TestRuleComplexWhitelist(t *testing.T) { } r := rules{ - inclusiveRules{patterns{"X-Amz-"}, blacklist{w}}, + inclusiveRules{patterns{"X-Amz-"}, excludeList{w}}, } if !r.IsValid("X-Amz-Blah") { diff --git a/aws/signer/v4/headers_test.go b/aws/signer/v4/headers_test.go new file mode 100644 index 00000000000..69b38844c87 --- /dev/null +++ b/aws/signer/v4/headers_test.go @@ -0,0 +1,37 @@ +// +build go1.7 + +package v4 + +import "testing" + +func TestAllowedQueryHoisting(t *testing.T) { + cases := map[string]struct { + Header string + ExpectHoist bool + }{ + "object-lock": { + Header: "X-Amz-Object-Lock-Mode", + ExpectHoist: false, + }, + "s3 metadata": { + Header: "X-Amz-Meta-SomeName", + ExpectHoist: false, + }, + "another header": { + Header: "X-Amz-SomeOtherHeader", + ExpectHoist: true, + }, + "non X-AMZ header": { + Header: "X-SomeOtherHeader", + ExpectHoist: false, + }, + } + + for name, c := range cases { + t.Run(name, func(t *testing.T) { + if e, a := c.ExpectHoist, allowedQueryHoisting.IsValid(c.Header); e != a { + t.Errorf("expect hoist %v, was %v", e, a) + } + }) + } +} diff --git a/aws/signer/v4/v4.go b/aws/signer/v4/v4.go index 1737c2686de..c1949859ad5 100644 --- a/aws/signer/v4/v4.go +++ b/aws/signer/v4/v4.go @@ -90,7 +90,7 @@ const ( ) var ignoredHeaders = rules{ - blacklist{ + excludeList{ mapRule{ authorizationHeader: struct{}{}, "User-Agent": struct{}{}, @@ -99,9 +99,9 @@ var ignoredHeaders = rules{ }, } -// requiredSignedHeaders is a whitelist for build canonical headers. +// requiredSignedHeaders is a allow list for build canonical headers. var requiredSignedHeaders = rules{ - whitelist{ + allowList{ mapRule{ "Cache-Control": struct{}{}, "Content-Disposition": struct{}{}, @@ -145,12 +145,13 @@ var requiredSignedHeaders = rules{ }, }, patterns{"X-Amz-Meta-"}, + patterns{"X-Amz-Object-Lock-"}, } -// allowedHoisting is a whitelist for build query headers. The boolean value +// allowedHoisting is a allow list for build query headers. The boolean value // represents whether or not it is a pattern. var allowedQueryHoisting = inclusiveRules{ - blacklist{requiredSignedHeaders}, + excludeList{requiredSignedHeaders}, patterns{"X-Amz-"}, }