Skip to content

Raise JWT::DecodeError for a malformed x5c header#740

Open
arpitjain099 wants to merge 1 commit into
jwt:mainfrom
arpitjain099:fix/x5c-header-type-guard
Open

Raise JWT::DecodeError for a malformed x5c header#740
arpitjain099 wants to merge 1 commit into
jwt:mainfrom
arpitjain099:fix/x5c-header-type-guard

Conversation

@arpitjain099

Copy link
Copy Markdown

The x5c verification path takes the header value straight off the token and hands it to parse_certificates, which calls .all? on it and maps every element through OpenSSL::X509::Certificate.new. When the header isn't the array of base64 strings the code assumes, the caller gets a raw exception instead of a JWT::DecodeError:

  • a bare string, a number, or nil raises NoMethodError (the value has no .all?)
  • an empty array, or an array holding a non-certificate, raises OpenSSL::X509::CertificateError

Both escape before any signature check runs, so code that rescues JWT::DecodeError for bad token input (which is the JWT.decode contract) sees an unexpected error type instead. key_finder.rb already guards the kid header this same way, so this just brings x5c in line with it.

The patch validates that the value is a non-empty array of strings or certificates and turns an OpenSSL parse failure into JWT::DecodeError. The added specs drive the real from() path with each malformed shape and assert JWT::DecodeError.

bundle exec rspec spec/jwt/x5c_key_finder_spec.rb is green. (Two ECDSA specs fail on my local OpenSSL build before and after this change, so they're unrelated.)

X5cKeyFinder#from passes the raw x5c header straight into
parse_certificates, which calls .all? on it and maps each element
through OpenSSL::X509::Certificate.new. If a token's x5c header is not
an array of base64 strings (a bare string, a number, nil, an empty
array, or an array holding a non-certificate), the finder raises an
uncaught NoMethodError or OpenSSL::X509::CertificateError before any
signature check, instead of the JWT::DecodeError callers expect from
bad token input.

Guard the input the same way key_finder.rb already guards the kid
header: validate it's a non-empty array of strings or certificates and
turn an OpenSSL parse failure into JWT::DecodeError. Adds specs driving
the real from() path with the malformed shapes.

Signed-off-by: arpitjain099 <arpitjain099@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant