From 157a788731f5c8ce543ed876304e6f86f272d138 Mon Sep 17 00:00:00 2001 From: windmgc Date: Tue, 15 Oct 2024 16:03:05 +0800 Subject: [PATCH 1/2] fix(request): remove unescape operation for user-input query params when building canonical querystring --- README.md | 4 ++ spec/02-requests/02-build_request_spec.lua | 60 ++++++++++++++++ spec/04-services/06-sns_spec.lua | 80 ++++++++++++++++++++++ src/resty/aws/request/build.lua | 2 +- src/resty/aws/request/signatures/utils.lua | 4 +- 5 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 spec/04-services/06-sns_spec.lua diff --git a/README.md b/README.md index 0d07d12..a499f4e 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/spec/02-requests/02-build_request_spec.lua b/spec/02-requests/02-build_request_spec.lua index 9e3a1b5..4c23a25 100644 --- a/spec/02-requests/02-build_request_spec.lua +++ b/spec/02-requests/02-build_request_spec.lua @@ -136,6 +136,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", @@ -184,6 +214,12 @@ describe("operations protocol", function() Body = binary_data, } + params_with_requestUri_params_and_query_param_input = { + Bucket = "hello", + Key = "world", + TestMember = "testvalue", + } + end) @@ -226,6 +262,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() diff --git a/spec/04-services/06-sns_spec.lua b/spec/04-services/06-sns_spec.lua new file mode 100644 index 0000000..6f8d1d9 --- /dev/null +++ b/spec/04-services/06-sns_spec.lua @@ -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) diff --git a/src/resty/aws/request/build.lua b/src/resty/aws/request/build.lua index 7b5794e..a01cdab 100644 --- a/src/resty/aws/request/build.lua +++ b/src/resty/aws/request/build.lua @@ -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 diff --git a/src/resty/aws/request/signatures/utils.lua b/src/resty/aws/request/signatures/utils.lua index 3d3a0f6..933e639 100644 --- a/src/resty/aws/request/signatures/utils.lua +++ b/src/resty/aws/request/signatures/utils.lua @@ -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 From d70bf0eab81820c9a7f8f20a2ca45a60a8511359 Mon Sep 17 00:00:00 2001 From: windmgc Date: Tue, 15 Oct 2024 16:07:55 +0800 Subject: [PATCH 2/2] tests: fix test --- spec/02-requests/02-build_request_spec.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/02-requests/02-build_request_spec.lua b/spec/02-requests/02-build_request_spec.lua index 4c23a25..de23f69 100644 --- a/spec/02-requests/02-build_request_spec.lua +++ b/spec/02-requests/02-build_request_spec.lua @@ -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