diff --git a/lib/resty/openidc.lua b/lib/resty/openidc.lua index cb78c05..a73b714 100644 --- a/lib/resty/openidc.lua +++ b/lib/resty/openidc.lua @@ -908,6 +908,10 @@ local function openidc_pem_from_jwk(opts, kid) end local x5c = jwk.x5c + if x5c and type(x5c) ~= 'table' then + log(WARN, "Found invalid JWK with x5c claim not being an array but a " .. type(x5c)) + x5c = nil + end if x5c and #(jwk.x5c) == 0 then log(WARN, "Found invalid JWK with empty x5c array, ignoring x5c claim") x5c = nil diff --git a/tests/spec/bearer_token_verification_spec.lua b/tests/spec/bearer_token_verification_spec.lua index 8baca8d..7834aca 100644 --- a/tests/spec/bearer_token_verification_spec.lua +++ b/tests/spec/bearer_token_verification_spec.lua @@ -203,6 +203,30 @@ describe("when the JWK specifies a kid and the JWKS does not contain a key with end) +describe("when the JWKS contains a broken x5c which is not an array", function() + test_support.start_server({ + verify_opts = { + discovery = { + jwks_uri = "http://127.0.0.1/jwk", + } + }, + jwk = test_support.load("/spec/rsa_key_jwk_with_broken_x5c.json"), + }) + teardown(test_support.stop_server) + local jwt = test_support.trim(http.request("http://127.0.0.1/jwt")) + local _, status = http.request({ + url = "http://127.0.0.1/verify_bearer_token", + headers = { authorization = "Bearer " .. jwt } + }) + it("the token is invalid", function() + assert.are.equals(401, status) + end) + it("an error is logged", function() + assert.error_log_contains("Found invalid JWK with x5c claim not being an array but a string") + end) + +end) + describe("when the JWK specifies no kid and the JWKS contains multiple keys", function() test_support.start_server({ verify_opts = { diff --git a/tests/spec/rsa_key_jwk_with_broken_x5c.json b/tests/spec/rsa_key_jwk_with_broken_x5c.json new file mode 100644 index 0000000..f7863b5 --- /dev/null +++ b/tests/spec/rsa_key_jwk_with_broken_x5c.json @@ -0,0 +1,10 @@ +{ + "keys": [ + { + "kty": "RSA", + "use": "sig", + "kid": "abcd", + "x5c": "MIIC+zCCAeOgAwIBAgIJAOlUwkUgtiAjMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNVBAMMCTEyNy4wLjAuMTAeFw0xNzEwMjAwODAyMzBaFw0yNzEwMTgwODAyMzBaMBQxEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMLGOeOLW3uZr6jbrkE4i+Cp9LcvfWhOcff8D68qmcWTwfYSDWTGKPbME83EuFwrpVzBZqIV2VaR7L5uX3+5MZij2DeG52Gdv+QnP0JlyHAxRWnNWSYu+ZURlwhDBi7g+rxTq/3/8DeFZQJtf6/pcWxLidwe6fQpQK0XkbRfxi3os0+YAEDedSyVzsIP9buz2KkjtHJ+RWxTGC61J/vJY7ruSVBDkPLBbMHFkTRUqATZ76B/DDtn5lyctbTUZKUUGljiwvu8zK2thp5CjMnP8DcCP0e8ZT5IUBN73VYksvf3Die8+axKUuFAyYRjv8mKbWXRFwJyUelC72R6pvcTBzcCAwEAAaNQME4wHQYDVR0OBBYEFEp61+QOEp6ZR/GpTood068poIf3MB8GA1UdIwQYMBaAFEp61+QOEp6ZR/GpTood068poIf3MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADqM/3yygJOF+k8AXPk2AGOfF7EMtm8GYVETUBwunYqgPHMoZj/+/IfHYg0BNx4T5Uh7yABvICO8KCpIrog0boopCNBlrkKs1L8WGnK9L8EQinA2JM+rL1UBAuPVFLGdT9LEjhwoJsRrRet9Pt79+iHP4kS2priuwKHOzsGwmj7Ptstx4lf6dOwElgGlxNDI8YnG4a4NlOQ0HMGtaS/bvB8hMPGRb8uCmnlrPVOQFOkUCwTTA5D1DjWmXg+aCwGf313MyH8y0TQ8aNkxJkcHHGTZELXmS+t9BnYvpNm+sQkqfVkwxgnP/R8wPH36rnID6QSH6/mFhz6S21qK5p3vVys=" + } + ] +}