Skip to content

Instantly share code, notes, and snippets.

@saibotsivad
Last active January 28, 2020 02:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saibotsivad/7cdaf44c83eec9209316b35c2f4052eb to your computer and use it in GitHub Desktop.
Save saibotsivad/7cdaf44c83eec9209316b35c2f4052eb to your computer and use it in GitHub Desktop.
Possibly Inaccurate AWS Signature V4 Tests

While writing a JavaScript library to generate AWS Signature V4 Requests, I have come across what I believe are inaccuracies in the provided V4 test suite.

This gist documents the AWS signature tests that I believe are inaccurate. If I find my understanding to be inaccurate, or if the tests are corrected by AWS, I will update this gist.

Note: The official test suite is provided by AWS here but I will link to the version I have put on Github here, so that I can better link to specific tests.

AWS Test

According to the AWS test get-header-value-multiline, the request header My-Header1 looks like:

GET / HTTP/1.1
Host: example.amazonaws.com
My-Header1: value1
  value2
     value3
X-Amz-Date:20150830T123600Z

And should normalize to the this:

my-header1:value1,value2,value3

However, my understanding of the HTTP request specs (see here for discussion) is that a multi-line request should normalize to a single line with spaces:

My-Header: A
  B
    C

Would be equivalent to:

My-Header: A B C

According to the AWS specs that means the header should normalize to:

my-header1:value1 value2 value3

In fact, comma-delimited would imply that this was not a multi-line header, but three headers of the same key:

My-Header: A
My-Header: B
My-Header: C
=>
My-Header: A, B, C

My understanding is that the Canonical Request should instead look like:

GET
/

host:example.amazonaws.com
my-header1:value1 value2 value3
x-amz-date:20150830T123600Z

host;my-header1;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

AWS Test

The UTF8 test shows the path /ሴ becomes /%E1%88%B4 which is encoded only once.

However, the Task 1 specs say that all request paths should be encoded twice:

Normalize URI paths according to RFC 3986. Remove redundant and relative path components. Each path segment must be URI-encoded twice (except for Amazon S3 which only gets URI-encoded once).

In fact, as an example it shows /documents and settings/ double encoded to /documents%2520and%2520settings/ since encodes to %20 which encodes to %2520

Therefore /ሴ should encode the first time to /%E1%88%B4 and the second time to /%25E1%2588%25B4 which should be the path component of the canonical request.

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