diff --git a/changelog/unreleased/kong/fix-jwt-plugin-rsa-public-key-b64decoded.yml b/changelog/unreleased/kong/fix-jwt-plugin-rsa-public-key-b64decoded.yml new file mode 100644 index 000000000000..71a90d424b28 --- /dev/null +++ b/changelog/unreleased/kong/fix-jwt-plugin-rsa-public-key-b64decoded.yml @@ -0,0 +1,3 @@ +message: "**jwt**: ensure `rsa_public_key` isn't base64-decoded." +type: bugfix +scope: Plugin diff --git a/kong/plugins/jwt/handler.lua b/kong/plugins/jwt/handler.lua index 45af8fd64c85..798dac4ef6fe 100644 --- a/kong/plugins/jwt/handler.lua +++ b/kong/plugins/jwt/handler.lua @@ -205,11 +205,17 @@ local function do_authentication(conf) return false, unauthorized("Invalid algorithm", www_authenticate_with_error) end - local jwt_secret_value = algorithm ~= nil and algorithm:sub(1, 2) == "HS" and - jwt_secret.secret or jwt_secret.rsa_public_key + local is_symmetric_algorithm = algorithm ~= nil and algorithm:sub(1, 2) == "HS" + local jwt_secret_value - if conf.secret_is_base64 then - jwt_secret_value = jwt:base64_decode(jwt_secret_value) + if is_symmetric_algorithm and conf.secret_is_base64 then + jwt_secret_value = jwt:base64_decode(jwt_secret.secret) + elseif is_symmetric_algorithm then + jwt_secret_value = jwt_secret.secret + else + -- rsa_public_key is either nil or a valid plain text pem file, it can't be base64 decoded. + -- see #13710 + jwt_secret_value = jwt_secret.rsa_public_key end if not jwt_secret_value then diff --git a/spec/03-plugins/16-jwt/03-access_spec.lua b/spec/03-plugins/16-jwt/03-access_spec.lua index e136dd8f50aa..77541b70e360 100644 --- a/spec/03-plugins/16-jwt/03-access_spec.lua +++ b/spec/03-plugins/16-jwt/03-access_spec.lua @@ -735,6 +735,23 @@ for _, strategy in helpers.each_strategy() do assert.equal("jwt_tests_rsa_consumer_2", body.headers["x-consumer-username"]) assert.equal(rsa_jwt_secret_2.key, body.headers["x-credential-identifier"]) end) + it("proxies the request if conf.secret is base64", function() + PAYLOAD.iss = rsa_jwt_secret_2.key + local jwt = jwt_encoder.encode(PAYLOAD, fixtures.rs256_private_key, 'RS256') + local authorization = "Bearer " .. jwt + local res = assert(proxy_client:send { + method = "GET", + path = "/request", + headers = { + ["Authorization"] = authorization, + ["Host"] = "jwt5.test" + } + }) + local body = cjson.decode(assert.res_status(200, res)) + assert.equal(authorization, body.headers.authorization) + assert.equal("jwt_tests_rsa_consumer_2", body.headers["x-consumer-username"]) + assert.equal(rsa_jwt_secret_2.key, body.headers["x-credential-identifier"]) + end) end) describe("RS512", function()