-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Signer does not match official Signature Version 4 Test Suite #853
Comments
To add to this, the managing of duplicate query keys is a case where the SDK does match the behaviour of the Test Suite, but neither of these match the behaviour of the live S3 service. To show this, try the following (from console.log(new AWS.Signers.V4(new AWS.HttpRequest({path: '/?foo=b&foo=a'})).canonicalString()) Which gives:
As you can see, the SDK sorts the query key However, if you make a similar query directly to S3 (replace AKIDEXAMPLE with a valid Access Key): require('https').request({
hostname: 's3.amazonaws.com',
path: '/?foo=b&foo=a&' +
'X-Amz-Expires=86400&' +
'X-Amz-Date=20151226T200800Z&' +
'X-Amz-Algorithm=AWS4-HMAC-SHA256&' +
'X-Amz-Credential=AKIDEXAMPLE%2F20151226%2Fus-east-1%2Fs3%2Faws4_request&' +
'X-Amz-SignedHeaders=host&' +
'X-Amz-Signature=5'
}, res => res.pipe(process.stdout)).end() It responds with:
Which, if you format it a little nicer, you can see it expects the canonical query string to be:
So it a) doesn't sort the query key So this is an example of where the SDK doesn't match the live S3 service in signing behaviour – but it does seem to match the Test Suite. |
Ugh, the plot thickens even further... So if you try another service, for example, So something's definitely fishy. The S3 service differs from (at least) the ES service, as well as the docs/tests – and this SDK seems to be somewhere in the middle. |
And even further... It seems that many services don't decode the path correctly and so they have an incorrect expectation for the Canonical String. This also makes it impossible to include certain characters in the path of a request to these services because there's no way to sign them correctly. The TL;DR version is that S3 gets this particular thing right, and if you request Here's a simple example using curl (you can add $ curl 'https://es.us-east-1.amazonaws.com/_search/%3Fa=b%20c' \
-H 'Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20151227/us-east-1/es/aws4_request, SignedHeaders=host;x-amz-date, Signature=7' \
-H 'X-Amz-Date: 20151227T231859Z'
<InvalidSignatureException>
...
The Canonical String for this request should have been
'GET
/_search/%253Fa%3Db%2520c
... See how the expected Canonical String has not parsed the URL correctly, and actually encodes the This makes it impossible, for example, to include a query that has a '?' character in it – because if you URL encode it to curl 'https://es.us-east-1.amazonaws.com/_search/?a=b%20c' \
-H 'Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20151227/us-east-1/es/aws4_request, SignedHeaders=host;x-amz-date, Signature=7' \
-H 'X-Amz-Date: 20151227T231859Z'
<InvalidSignatureException>
...
The Canonical String for this request should have been
'GET
/_search/
a=b%20c
... Also note how the Funnily enough, S3 seems to get this one right. To wit: $ curl 'https://s3.amazonaws.com/_search/%3Fa=b%20c' \
-H 'Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20151227/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=7' \
-H 'X-Amz-Date: 20151227T234059Z' \
-H 'X-Amz-Content-Sha256: 1234123412341234'
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>SignatureDoesNotMatch</Code>
...
<CanonicalRequest>
GET
/_search/%3Fa%3Db%20c
... |
Alright, have dug further... It seems that everything's broken in this regard. None of the live services, or tests, or SDKs seem to show any consistency with how they manage the Canonical String – especially when it comes to URL encoding and query string parameters. Here's a table showing how each service expects you to create the canonical string (for the path and query portions)
|
As per usual, the forums have been an absolute ghost town on this whole thing... https://forums.aws.amazon.com/thread.jspa?messageID=693401 |
@mhart |
@chrisradek has there been any movement on this? |
@mhart I came here trying to debug this exact same discrepancy between Postman's AWS implementation and my own in-house library. Thank you for the detailed breakdown. I'm abandoning all hope. |
I am using aws4 RequestSigner to get the cononicalstring for execute-api service. The RequestSigner converts /@connections/abcd= to /%2540connections/abcd%253D Can you please let me know any workaround of this issue or if is there proper solution please share the same? |
Closing this issue because of inactivity, please re-open if anyone has any additional questions. |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread. |
There is a test suite provided here:
http://docs.aws.amazon.com/general/latest/gr/signature-v4-test-suite.html
And there is also documentation provided here:
http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
That says "Normalize URI paths according to RFC 3986 by removing redundant and relative path components".
As the documentation implies above, and as the test suite shows, there are some examples of requests (in
get-relative.sreq
andget-slashes.sreq
in the test suite, among others) where the request provided is, say,GET /foo/.. http/1.1
and the expected canonical request (inget-relative.creq
) is resolved to/
.However, this is not what the aws-sdk does:
Results in:
If the SDK was resolving according to the documentation (and test suite), then the canonical request would be
/whatever/
instead of///key//..//whatever/.
– so the SDK doesn't actually pass the test suite (I can provide you with the exact tests it fails if you like).An important thing to note here is that it appears that the actual AWS services themselves also don't appear to adhere to the documentation or test suite.
So, I'm left wondering if it's actually the test suite and documentation themselves that are incorrect – because both the SDK and actual AWS services appear not to do any normalisation whatsoever. However, it would be good to clarify this and determine which source is actually correct!
The text was updated successfully, but these errors were encountered: