Skip to content

Commit

Permalink
fix(bk-auth/legacy): patch for invalid params of old gateway (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
wklken authored Nov 7, 2023
1 parent a6822ab commit d530ead
Show file tree
Hide file tree
Showing 4 changed files with 280 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/apisix/plugins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@

上下文注入,优先级:18000 ~ 19000

- bk-legacy-invalid-params # priority: 18880 # 用于兼容老版本 go1.16 使用 `;` 作为 query string 分隔符
- bk-opentelemetry # priority: 18870 # 这个插件用于 opentelemetry, 需要尽量精准统计全局的耗时,同时需要注入 trace_id/span_id 作为后面所有插件自定义 opentelemetry 上报的 trace_id 即 parent span_id
- bk-not-found-handler # priority: 18860 # 该插件仅适用于由 operator 创建的默认根路由,用以规范化 404 消息。该插件以较高优先级结束请求返回 404 错误信息
- bk-request-id # priority: 18850
- bk-stage-context # priority: 18840
- bk-service-context # priority: 18830
- bk-service-context # priority: 18830 (abandonned)
- bk-resource-context # priority: 18820
- bk-status-rewrite # priority: 18815
- bk-verified-user-exempted-apps # priority: 18810 (will be deprecated)
Expand All @@ -31,8 +32,8 @@

认证:

- bk-workflow-parameters # priority: 18750
- bk-auth-parameters # priority: 18740
- bk-workflow-parameters # priority: 18750 (abandonned)
- bk-auth-parameters # priority: 18740 (abandonned)
- bk-auth-verify # priority: 18730

执行 - 响应:优先级:17500 ~ 18000
Expand Down
66 changes: 66 additions & 0 deletions src/apisix/plugins/bk-legacy-invalid-params.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
--
-- TencentBlueKing is pleased to support the open source community by making
-- 蓝鲸智云 - API 网关(BlueKing - APIGateway) available.
-- Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
-- Licensed under the MIT License (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
--
-- http://opensource.org/licenses/MIT
--
-- Unless required by applicable law or agreed to in writing, software distributed under
-- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
-- either express or implied. See the License for the specific language governing permissions and
-- limitations under the License.
--
-- We undertake not to change the open source license (MIT license) applicable
-- to the current version of the project delivered to anyone in the future.
--

-- # bk-legacy-invalid-params
--
-- For old gateway calling, because go 1.16 support both `&` and `;` as query string separator, but lua only support `&`
-- and in some case, the caller html escaped the `&` to `&`(it's ok for go 1.16 gateway)
-- so we need to adapat the old gateway calling.
-- e.g.
-- ?app_code=appC&app_secret=appC
-- ?app_code=appC&app_secret=appC
-- ?app_code=appC;app_secret=appC
-- ?a=1;a=2

local string_replace = require("pl.stringx").replace
local string_find = string.find
local core = require("apisix.core")

local schema = {}

local _M = {
version = 0.1,
priority = 18880,
name = "bk-legacy-invalid-params",
schema = schema,
}

function _M.check_schema(conf)
return core.schema.check(schema, conf)
end

function _M.rewrite(conf, ctx)
-- FIXME: 未来新的接口使用`;`也不生效, 怎么控制范围?

-- FIX 1
-- in golang 1.16: strings.IndexAny(key, "&;")
-- so here we just need to replace `;` to `&`, then reset the uri_args
-- args will be decoded like golang version

-- core.log.error(ctx.var.args)
-- only query string contains `;` should be processed
if ctx.var.args ~= nil and string_find(ctx.var.args, ";") then
local new_args = string_replace(ctx.var.args, ";", "&")
-- core.log.error("replace ; to &: ", new_args)
core.request.set_uri_args(ctx, new_args)
end
-- local args = core.request.get_uri_args()
-- core.log.error(core.json.delay_encode(args))
end

return _M
116 changes: 116 additions & 0 deletions src/apisix/t/bk-legacy-invalid-params.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#
# TencentBlueKing is pleased to support the open source community by making
# 蓝鲸智云 - API 网关(BlueKing - APIGateway) available.
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
# Licensed under the MIT License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://opensource.org/licenses/MIT
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions and
# limitations under the License.
#
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.
#

use t::APISIX 'no_plan';

log_level('debug');
repeat_each(1);
no_long_string();
no_root_location();

add_block_preprocessor(sub {
my ($block) = @_;

if (!$block->request) {
$block->set_value("request", "GET /t");
}
});

run_tests;

__DATA__
=== TEST 1: sanity
--- config
location /t {
content_by_lua_block {
local plugin = require("apisix.plugins.bk-legacy-invalid-params")
local ok, err = plugin.check_schema({})
if not ok then
ngx.say(err)
end
ngx.say("done")
}
}
--- response_body
done
=== TEST 2: add plugin
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"bk-legacy-invalid-params": {
},
"mocking": {
"content_type": "text/plain",
"response_status": 200,
"response_example": "args:$args\n"
}
},
"upstream": {
"nodes": {
"127.0.0.1:1982": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)
if code >= 300 then
ngx.status = code
end
-- code is 201, body is passed
ngx.say(body)
}
}
--- response_body
passed
=== TEST 3: call no args
--- request
GET /hello
--- response_body
args:
=== TEST 4: call with normal args
--- request
GET /hello?a=1&b=2
--- response_body
args:a=1&b=2
=== TEST 5: call with `;`
--- request
GET /hello?a=1;b=2
--- response_body
args:a=1&b=2
=== TEST 6: call with `&`
--- request
GET /hello?a=1&b=2
--- response_body
args:a=1&amp&b=2
=== TEST 7: call with `&`
--- request
GET /hello?a=1&b=2
--- response_body
args:a=1&amp&amp&b=2
94 changes: 94 additions & 0 deletions src/apisix/tests/test-bk-legacy-invalid-params.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
--
-- TencentBlueKing is pleased to support the open source community by making
-- 蓝鲸智云 - API 网关(BlueKing - APIGateway) available.
-- Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
-- Licensed under the MIT License (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
--
-- http://opensource.org/licenses/MIT
--
-- Unless required by applicable law or agreed to in writing, software distributed under
-- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
-- either express or implied. See the License for the specific language governing permissions and
-- limitations under the License.
--
-- We undertake not to change the open source license (MIT license) applicable
-- to the current version of the project delivered to anyone in the future.
--

local core = require("apisix.core")

local plugin = require("apisix.plugins.bk-legacy-invalid-params")

describe(
"bk-legacy-invalid-params",
function()
context(
"rewrite",
function()
local ctx
before_each(
function()
ctx = {
var = {}
}
stub(core.request, "set_uri_args")
end
)

after_each(
function()
-- ngx.req.clear_header:revert()
core.request.set_uri_args:revert()
end
)

it(
"no args",
function()
plugin.rewrite({}, ctx)

assert.stub(core.request.set_uri_args).was_not_called()
end
)
it(
"normal args with &",
function()
ctx.var.args = "a=1&b=2"
plugin.rewrite({}, ctx)

assert.stub(core.request.set_uri_args).was_not_called()
end
)
it(
"args with ;",
function()
ctx.var.args = "a=1;b=2"
plugin.rewrite({}, ctx)

assert.stub(core.request.set_uri_args).was_called_with(ctx, "a=1&b=2")
end
)
it(
"args with &",
function()
ctx.var.args = "a=1&b=2"
plugin.rewrite({}, ctx)

assert.stub(core.request.set_uri_args).was_called_with(ctx, "a=1&amp&b=2")
end
)
it(
"args with &",
function()
ctx.var.args = "a=1&b=2"
plugin.rewrite({}, ctx)

assert.stub(core.request.set_uri_args).was_called_with(ctx, "a=1&amp&amp&b=2")
end
)

end
)
end
)

0 comments on commit d530ead

Please sign in to comment.