From 70d91d0ca9d3f2752d9d79ab09ac5201d10c64fb Mon Sep 17 00:00:00 2001 From: Douglas Lee Date: Tue, 13 Dec 2022 10:32:28 +0800 Subject: [PATCH 1/5] fix(jwt): deny requests that have different tokens in the jwt token search locations. --- CHANGELOG.md | 2 ++ kong/plugins/jwt/handler.lua | 42 +++++++++++++++++++---- spec/03-plugins/16-jwt/03-access_spec.lua | 15 ++++++++ 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9368302ee14..9259321e881 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -94,6 +94,8 @@ - **Zipkin**: Fix an issue where the global plugin's sample ratio overrides route-specific. [#9877](https://github.com/Kong/kong/pull/9877) +- **JWT**: Deny requests that have different tokens in the jwt token search locations. Thanks, Jackson 'Che-Chun' Kuo from Latacora. + [#9946](https://github.com/Kong/kong/pull/9946) ### Dependencies diff --git a/kong/plugins/jwt/handler.lua b/kong/plugins/jwt/handler.lua index de1bfdd0d2e..3792f0c23c6 100644 --- a/kong/plugins/jwt/handler.lua +++ b/kong/plugins/jwt/handler.lua @@ -8,8 +8,10 @@ local kong = kong local type = type local error = error local ipairs = ipairs +local pairs = pairs local tostring = tostring local re_gmatch = ngx.re.gmatch +local table_insert = table.insert local JwtHandler = { @@ -24,11 +26,22 @@ local JwtHandler = { -- @param conf Plugin configuration -- @return token JWT token contained in request (can be a table) or nil -- @return err -local function retrieve_token(conf) +local function retrieve_tokens(conf) + local token_set = {} local args = kong.request.get_query() for _, v in ipairs(conf.uri_param_names) do - if args[v] then - return args[v] + local token = args[v] -- can be a table + if token then + if type(token) == "table" then + for _, t in ipairs(token) do + if t ~= "" then + token_set[t] = true + end + end + + elseif token ~= "" then + token_set[token] = true + end end end @@ -36,7 +49,7 @@ local function retrieve_token(conf) for _, v in ipairs(conf.cookie_names) do local cookie = var["cookie_" .. v] if cookie and cookie ~= "" then - return cookie + token_set[cookie] = true end end @@ -60,10 +73,27 @@ local function retrieve_token(conf) end if m and #m > 0 then - return m[1] + if m[1] ~= "" then + token_set[m[1]] = true + end end end end + + local tokens = {} + for token, _ in pairs(token_set) do + table_insert(tokens, token) + end + + if #tokens == 0 then + return nil + end + + if #tokens == 1 then + return tokens[1] + end + + return tokens end @@ -117,7 +147,7 @@ end local function do_authentication(conf) - local token, err = retrieve_token(conf) + local token, err = retrieve_tokens(conf) if err then return error(err) end diff --git a/spec/03-plugins/16-jwt/03-access_spec.lua b/spec/03-plugins/16-jwt/03-access_spec.lua index 8ab5207afdc..dfa90e592d0 100644 --- a/spec/03-plugins/16-jwt/03-access_spec.lua +++ b/spec/03-plugins/16-jwt/03-access_spec.lua @@ -396,6 +396,21 @@ for _, strategy in helpers.each_strategy() do assert.falsy(ok) assert.match("Code: Unauthenticated", err) end) + + it("reject if multiple different tokens found", function() + PAYLOAD.iss = jwt_secret.key + local jwt = jwt_encoder.encode(PAYLOAD, jwt_secret.secret) + local res = assert(proxy_client:send { + method = "GET", + path = "/request?jwt=" .. jwt, + headers = { + ["Authorization"] = "Bearer invalid.jwt.token", + ["Host"] = "jwt1.com", + } + }) + local body = cjson.decode(assert.res_status(401, res)) + assert.same({ message = "Multiple tokens provided" }, body) + end) end) describe("HS256", function() From 9cb24eb22ead4fb8203285d6f9cc5b9d0e3a7e8c Mon Sep 17 00:00:00 2001 From: Yusheng Li Date: Tue, 13 Dec 2022 15:23:37 +0800 Subject: [PATCH 2/5] Update CHANGELOG.md Co-authored-by: Datong Sun --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9259321e881..32802990226 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -94,7 +94,7 @@ - **Zipkin**: Fix an issue where the global plugin's sample ratio overrides route-specific. [#9877](https://github.com/Kong/kong/pull/9877) -- **JWT**: Deny requests that have different tokens in the jwt token search locations. Thanks, Jackson 'Che-Chun' Kuo from Latacora. +- **JWT**: Deny requests that have different tokens in the jwt token search locations. Thanks Jackson 'Che-Chun' Kuo from Latacora for reporting this issue. [#9946](https://github.com/Kong/kong/pull/9946) ### Dependencies From 9e59595a39d0f472ed54637ecf115c51d9ee90d1 Mon Sep 17 00:00:00 2001 From: Douglas Lee Date: Wed, 21 Dec 2022 17:10:53 +0800 Subject: [PATCH 3/5] add tokens_n variable to avoid multiple call of #tokens --- kong/plugins/jwt/handler.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kong/plugins/jwt/handler.lua b/kong/plugins/jwt/handler.lua index 3792f0c23c6..23c623bcc88 100644 --- a/kong/plugins/jwt/handler.lua +++ b/kong/plugins/jwt/handler.lua @@ -80,16 +80,18 @@ local function retrieve_tokens(conf) end end + local tokens_n = 0 local tokens = {} for token, _ in pairs(token_set) do - table_insert(tokens, token) + tokens_n = tokens_n + 1 + tokens[tokens_n] = token end - if #tokens == 0 then + if tokens_n == 0 then return nil end - if #tokens == 1 then + if tokens_n == 1 then return tokens[1] end From 32d87e884d2d73cea2d38a6798f79253e9f83fba Mon Sep 17 00:00:00 2001 From: Douglas Lee Date: Thu, 22 Dec 2022 16:15:06 +0800 Subject: [PATCH 4/5] cleanup --- kong/plugins/jwt/handler.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/kong/plugins/jwt/handler.lua b/kong/plugins/jwt/handler.lua index 23c623bcc88..2288a8351e9 100644 --- a/kong/plugins/jwt/handler.lua +++ b/kong/plugins/jwt/handler.lua @@ -11,7 +11,6 @@ local ipairs = ipairs local pairs = pairs local tostring = tostring local re_gmatch = ngx.re.gmatch -local table_insert = table.insert local JwtHandler = { From e937f3968821b7b3ce2adca192e16cab142f795e Mon Sep 17 00:00:00 2001 From: Douglas Lee Date: Thu, 22 Dec 2022 16:15:52 +0800 Subject: [PATCH 5/5] update CHANGELOG.md --- CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32802990226..49219fb74dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,9 +69,16 @@ ## Unreleased +### Breaking Changes + +#### Plugins + +- **JWT**: JWT plugin now denies a request that has different tokens in the jwt token search locations. + [#9946](https://github.com/Kong/kong/pull/9946) + ### Additions -### Plugins +#### Plugins - **Zipkin**: Add support to set the durations of Kong phases as span tags through configuration property `config.phase_duration_flavor`.