diff --git a/.changelog/4b776031a69541caa111950fd7dbe4fa.json b/.changelog/4b776031a69541caa111950fd7dbe4fa.json new file mode 100644 index 00000000000..79424d94cb4 --- /dev/null +++ b/.changelog/4b776031a69541caa111950fd7dbe4fa.json @@ -0,0 +1,8 @@ +{ + "id": "4b776031-a695-41ca-a111-950fd7dbe4fa", + "type": "bugfix", + "description": "Keep Object-Lock headers a header when presigning Sigv4 signing requests", + "modules": [ + "." + ] +} \ No newline at end of file diff --git a/aws/signer/internal/v4/header_rules.go b/aws/signer/internal/v4/header_rules.go index 5e5953c7386..c61955ad5b9 100644 --- a/aws/signer/internal/v4/header_rules.go +++ b/aws/signer/internal/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 include 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 AllowList checks if the value is within the AllowList +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 exclude listing +type ExcludeList struct { Rule } -// IsValid for Whitelist checks if the value is within the Whitelist -func (b Blacklist) IsValid(value string) bool { +// IsValid for AllowList checks if the value is within the AllowList +func (b ExcludeList) IsValid(value string) bool { return !b.Rule.IsValid(value) } diff --git a/aws/signer/internal/v4/headers.go b/aws/signer/internal/v4/headers.go index b62d985cce1..85a1d8f032f 100644 --- a/aws/signer/internal/v4/headers.go +++ b/aws/signer/internal/v4/headers.go @@ -2,7 +2,7 @@ package v4 // IgnoredHeaders is a list of headers that are ignored during signing var IgnoredHeaders = Rules{ - Blacklist{ + ExcludeList{ MapRule{ "Authorization": struct{}{}, "User-Agent": struct{}{}, @@ -11,9 +11,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{}{}, @@ -56,12 +56,13 @@ var RequiredSignedHeaders = Rules{ "X-Amz-Tagging": struct{}{}, }, }, + Patterns{"X-Amz-Object-Lock-"}, Patterns{"X-Amz-Meta-"}, } -// AllowedQueryHoisting is a whitelist for Build query headers. The boolean value +// AllowedQueryHoisting is a allowed 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-"}, } diff --git a/aws/signer/internal/v4/headers_test.go b/aws/signer/internal/v4/headers_test.go new file mode 100644 index 00000000000..debf07788ae --- /dev/null +++ b/aws/signer/internal/v4/headers_test.go @@ -0,0 +1,35 @@ +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) + } + }) + } +}