Skip to content
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

fix(request): remove unescape operation for user-input query params when building canonical querystring #132

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ Release process:
1. upload using: `VERSION=x.y.z APIKEY=abc... make upload`
1. test installing the rock from LuaRocks

### Unreleased

- fix: fix an issue when publish sns message with urlencode reserved character(+/%)
[132](https://github.com/Kong/lua-resty-aws/pull/132)

### 1.5.4 (23-Sep-2024)

Expand Down
62 changes: 62 additions & 0 deletions spec/02-requests/02-build_request_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ describe("operations protocol", function()

local build_request
local operation, operation_with_payload_field
local operation_with_requestUri_params_and_query_param_input
local config, config_with_payload
local params, params_with_payload
local params_with_requestUri_params_and_query_param_input
local snapshot
local binary_data

Expand Down Expand Up @@ -136,6 +138,36 @@ describe("operations protocol", function()
},
}

operation_with_requestUri_params_and_query_param_input = {
name = "PutObject",
http = {
method = "PUT",
requestUri = "/{Bucket}/{Key+}?testparam=testparamvalue"
},
input = {
type = "structure",
required = {
"Bucket",
"Key"
},
members = {
TestMember = {
type = "string",
},
Bucket = {
type = "string",
location = "uri",
locationName = "Bucket"
},
Key = {
type = "string",
location = "uri",
locationName = "Key"
},
},
},
}

config = {
apiVersion = "2011-06-15",
--endpointPrefix = "sts",
Expand Down Expand Up @@ -184,6 +216,12 @@ describe("operations protocol", function()
Body = binary_data,
}

params_with_requestUri_params_and_query_param_input = {
Bucket = "hello",
Key = "world",
TestMember = "testvalue",
}

end)


Expand Down Expand Up @@ -226,6 +264,30 @@ describe("operations protocol", function()
}, request)
end)

it("query: undefined location params go into query table, with requestUri query params added", function ()
config_with_payload.protocol = "query"

local request = build_request(operation_with_requestUri_params_and_query_param_input,
config_with_payload, params_with_requestUri_params_and_query_param_input)
assert.same({
headers = {
["X-Amz-Target"] = "s3.PutObject",
["Host"] = "s3.amazonaws.com",
},
method = 'PUT',
path = '/hello/world',
host = 's3.amazonaws.com',
port = 443,
query = {
Action = "PutObject",
Version = "2006-03-01",
testparam = "testparamvalue",
TestMember = "testvalue",
}
}, request)

end)


it("rest-json: querystring, uri, header and body params", function()

Expand Down
80 changes: 80 additions & 0 deletions spec/04-services/06-sns_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
setmetatable(_G, nil)

local AWS = require("resty.aws")
local AWS_global_config = require("resty.aws.config").global


local config = AWS_global_config
config.tls = true
local aws = AWS(config)


aws.config.credentials = aws:Credentials {
accessKeyId = "test_id",
secretAccessKey = "test_key",
}

aws.config.region = "test_region"
aws.config.dry_run = true

describe("SNS service", function()
local sns
local origin_time

setup(function()
origin_time = ngx.time
ngx.time = function () --luacheck: ignore
return 1667543171
end
end)

teardown(function ()
ngx.time = origin_time --luacheck: ignore
end)

before_each(function()
sns = assert(aws:SNS({}))
end)

after_each(function()
end)

local testcases = {
publish = {
{
TopicArn = "arn:aws:sns:test-region:000000000000:test-topic",
Message = '{"timestamp":"1980-01-02T08:11:12.123+01:00","message":"test%abc%22"}', -- this is not an urlencoded message value
},
{
['headers'] = {
['Authorization'] = 'AWS4-HMAC-SHA256 Credential=test_id/20221104/test_region/sns/aws4_request, SignedHeaders=host;x-amz-date, Signature=9a83a7bafbccd6c3214091baf22eb1d1e507327be18f7ad5cf8ccc45ac335e48',
['Host'] = 'sns.test_region.amazonaws.com',
['X-Amz-Date'] = '20221104T062611Z',
},
['host'] = 'sns.test_region.amazonaws.com',
['method'] = 'POST',
['path'] = '/',
['proxy_opts'] = {},
['port'] = 443,
['query'] = {
['Action'] = 'Publish',
['Version'] = '2010-03-31',
['Message'] = '{"timestamp":"1980-01-02T08:11:12.123+01:00","message":"test%abc%22"}',
['TopicArn'] = 'arn:aws:sns:test-region:000000000000:test-topic',
},
['tls'] = true,
},
},
}

for api, test in pairs(testcases) do
it("SecretsManager:" .. api, function()
local param = test[1]
local expected_result_aws = test[2]

local result_aws = assert(sns[api](sns, param))

assert.same(expected_result_aws, result_aws)
end)
end
end)
2 changes: 1 addition & 1 deletion src/resty/aws/request/build.lua
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ local function build_request(operation, config, params)
request.path = path

for k,v in pairs(parse_query(query)) do
request.query[k] = v
request.query[ngx.unescape_uri(k)] = ngx.unescape_uri(v)
end

local payload_member = operation.input and operation.input.payload
Expand Down
4 changes: 2 additions & 2 deletions src/resty/aws/request/signatures/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ local function canonicalise_query_string(query)

elseif type(query) == "table" then
for key, val in pairs(query) do
key = ngx.unescape_uri(key):gsub("[^%w%-%._~]", percent_encode)
val = ngx.unescape_uri(val):gsub("[^%w%-%._~]", percent_encode)
key = key:gsub("[^%w%-%._~]", percent_encode)
val = val:gsub("[^%w%-%._~]", percent_encode)
q[#q+1] = key .. "=" .. val
end

Expand Down
Loading