bugfix: Ensure SignatureV4 sorts query parameters by their URL-encoded names … #3200
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
🐛 Bug: Incorrect Query Parameter Sorting Causes Signature Mismatch
Description
When using AWS SDK, requests fail with a signature mismatch if one of the query parameters is an array with 10 or more elements.
Error message:
The request signature we calculated does not match the signature you provided.
⚙️ Root Cause
The issue occurs due to incorrect sorting of query parameters when generating the canonical query string for signing.
Currently, parameters are being sorted before URL encoding, but according to AWS documentation, they must be sorted after encoding.
“You must also sort the parameters in the canonical query string alphabetically by key name. The sorting occurs after encoding.”
This incorrect order in ksort causes an invalid canonical string and therefore an invalid signature.
🧩 Example
Request URL:
https://example.com/service?param[0]=1111¶m[1]=1111¶m[10]=1111¶m[2]=1111¶m[3]=1111¶m[4]=1111¶m[5]=1111¶m[6]=1111¶m[7]=1111¶m[8]=1111¶m[9]=1111
Current (incorrect) sorting result:
array(11) {
["param[0]"] => "1111"
["param[10]"] => "1111"
["param[1]"] => "1111"
["param[2]"] => "1111"
["param[3]"] => "1111"
["param[4]"] => "1111"
["param[5]"] => "1111"
["param[6]"] => "1111"
["param[7]"] => "1111"
["param[8]"] => "1111"
["param[9]"] => "1111"
}
Expected (correct) sorting result:
array(11) {
["param[0]"] => "1111"
["param[1]"] => "1111"
["param[10]"] => "1111"
["param[2]"] => "1111"
["param[3]"] => "1111"
["param[4]"] => "1111"
["param[5]"] => "1111"
["param[6]"] => "1111"
["param[7]"] => "1111"
["param[8]"] => "1111"
["param[9]"] => "1111"
}
✅ Proposed Fix
Sort query parameters after URL encoding instead of before, following the official AWS signing specification.
📚 References
AWS Signature Version 4 – Creating a Canonical Request
Our fix in async aws library:
async-aws/aws#1938
Probably fix the issue: #3132