fix(aws-lambda): IAM auth fails with URL-encoded or multi-value query parameters#13520
Merged
nic-6443 merged 1 commit intoJun 12, 2026
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes AWS SigV4 (IAM) request signing in the aws-lambda plugin when the client request contains URL-encoded query parameters, repeated parameters, or valueless parameters, which previously could lead to InvalidSignatureException (403) from AWS.
Changes:
- Implement RFC3986/AWS-compliant query parameter percent-encoding and canonical sorting for SigV4 signing in
apisix/plugins/aws-lambda.lua. - Add a new test that emulates AWS-side SigV4 verification to catch mismatches between the request received and the signature provided (
t/plugin/aws-lambda.t).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
apisix/plugins/aws-lambda.lua |
Reworks SigV4 canonical query string construction (encoding, multi-value expansion, valueless handling, sorting) and uses it during signature computation. |
t/plugin/aws-lambda.t |
Adds an end-to-end regression test that recomputes SigV4 from the received request to ensure signing correctness for encoded/multi/valueless query params. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
shreemaan-abhishek
approved these changes
Jun 12, 2026
membphis
approved these changes
Jun 12, 2026
AlinsRan
approved these changes
Jun 12, 2026
wistefan
pushed a commit
to wistefan/apisix
that referenced
this pull request
Jun 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Description
When the aws-lambda plugin uses IAM authorization and the client request carries any query parameter that needs URL encoding (e.g. a space), AWS rejects the invocation with 403
InvalidSignatureException.The root cause is in the canonical query string construction:
core.request.get_uri_args()already returns percent-decoded args, the plugin runsngx.unescape_uri()over them and signs the decoded string, while the query actually sent on the wire is re-encoded by lua-resty-http (ngx.encode_argson the table). So the signature is computed over different bytes than what AWS receives, e.g.with space=a/b cis signed butwith%20space=a%2Fb%20cis sent. The same lines also corrupt the canonical string for repeated args (the table value is stringified totable: 0x...) and for valueless args (?flagis signed asflag=truebut sent asflag).This PR builds the canonical query string per the SigV4 spec: every name and value is percent-encoded with the RFC3986 unreserved set (AWS UriEncode rules), repeated args are expanded into one pair per value, a valueless arg gets an empty value, and the pairs are sorted by encoded name then encoded value. The plugin now also passes this exact string as
params.query— lua-resty-http sends a string query through unmodified — so the signed query string and the wire query string are identical by construction.The new test emulates the AWS server-side validation: the mock rebuilds the canonical request from the request it actually received and recomputes the signature with the known secret key, so it catches any mismatch between what is signed and what is sent.
Which issue(s) this PR fixes:
Fixes #11097
Checklist