Skip to content

Commit

Permalink
fix: Trim extra spaces in signed header values (#1065)
Browse files Browse the repository at this point in the history
Trim extra spaces in signed header values for creating canonical 
request string for v4 signature.

As per S3 spec:
https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
  • Loading branch information
poornas authored and nitisht committed Jan 24, 2019
1 parent a78f77b commit 17db16b
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 2 deletions.
3 changes: 2 additions & 1 deletion functional_tests.go
Expand Up @@ -653,7 +653,8 @@ func testPutObjectWithMetadata() {
customContentType := "custom/contenttype"

args["metadata"] = map[string][]string{
"Content-Type": {customContentType},
"Content-Type": {customContentType},
"X-Amz-Meta-CustomKey": {"extra spaces in value"},
}

n, err := c.PutObject(bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{
Expand Down
2 changes: 1 addition & 1 deletion pkg/s3signer/request-signature-v4.go
Expand Up @@ -151,7 +151,7 @@ func getCanonicalHeaders(req http.Request, ignoredHeaders map[string]bool) strin
if idx > 0 {
buf.WriteByte(',')
}
buf.WriteString(v)
buf.WriteString(signV4TrimAll(v))
}
buf.WriteByte('\n')
}
Expand Down
9 changes: 9 additions & 0 deletions pkg/s3signer/utils.go
Expand Up @@ -21,6 +21,7 @@ import (
"crypto/hmac"
"crypto/sha256"
"net/http"
"strings"
)

// unsignedPayload - value to be set to X-Amz-Content-Sha256 header when
Expand All @@ -47,3 +48,11 @@ func getHostAddr(req *http.Request) string {
}
return req.URL.Host
}

// Trim leading and trailing spaces and replace sequential spaces with one space, following Trimall()
// in http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
func signV4TrimAll(input string) string {
// Compress adjacent spaces (a space is determined by
// unicode.IsSpace() internally here) to one space and return
return strings.Join(strings.Fields(input), " ")
}
29 changes: 29 additions & 0 deletions pkg/s3signer/utils_test.go
Expand Up @@ -84,3 +84,32 @@ func TestEncodeURL2Path(t *testing.T) {
}

}

// TestSignV4TrimAll - tests the logic of TrimAll() function
func TestSignV4TrimAll(t *testing.T) {
testCases := []struct {
// Input.
inputStr string
// Expected result.
result string
}{
{"本語", "本語"},
{" abc ", "abc"},
{" a b ", "a b"},
{"a b ", "a b"},
{"a b", "a b"},
{"a b", "a b"},
{" a b c ", "a b c"},
{"a \t b c ", "a b c"},
{"\"a \t b c ", "\"a b c"},
{" \t\n\u000b\r\fa \t\n\u000b\r\f b \t\n\u000b\r\f c \t\n\u000b\r\f", "a b c"},
}

// Tests generated values from url encoded name.
for i, testCase := range testCases {
result := signV4TrimAll(testCase.inputStr)
if testCase.result != result {
t.Errorf("Test %d: Expected signV4TrimAll result to be \"%s\", but found it to be \"%s\" instead", i+1, testCase.result, result)
}
}
}

0 comments on commit 17db16b

Please sign in to comment.