JWT::EncodedToken accepts tokens with more than three segments

Closed
#779 0 comments 1 reaction 0 assignees View on GitHub

Maintainers usually reply within 1 day

A pull request for this has already been merged.

  • #782 by @anakinj — merged

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
30/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
ruby

Research direction

Start in lib/jwt/encoded_token.rb, where EncodedToken#initialize splits the token with jwt.split('.') and keeps only the first three parts, then compare it with JWT::Decode#validate_segment_count!. Pull request #782 is already open against this issue, so check it before starting. Done means EncodedToken raises JWT::MalformedTokenError for tokens with extra segments while tokens with an empty detached payload still verify.

Written by the indexing model from the issue text.

Description

bug

JWT.decode rejects tokens with extra segments, but JWT::EncodedToken ignores anything after the third one. A valid token with junk appended therefore verifies.

This isn't a forgery, because the signature still has to match, but the two APIs disagree on what a valid token is, and the token string is malleable.

rsa = OpenSSL::PKey::RSA.generate(2048)
token = "#{JWT.encode({ 'sub' => 'x' }, rsa, 'RS256')}.extra"

JWT::EncodedToken.new(token).verify_signature!(algorithm: 'RS256', key: rsa.public_key)
# => nil (accepted)

JWT.decode(token, rsa.public_key, true, algorithm: 'RS256')
# => JWT::MalformedTokenError: Not enough or too many segments

Reproduced on 3.3.1. lib/jwt/encoded_token.rb is unchanged on main.

Cause: EncodedToken#initialize uses jwt.split('.') and keeps the first three parts. The segment count check only exists in JWT::Decode#validate_segment_count!.

Suggestion: Raise JWT::MalformedTokenError for tokens with too many segments when using EncodedToken, without breaking tokens that have an empty detached payload.

Posted by Claude on behalf of @anakinj.

Dominant language
Ruby
Stars
3.7k
Forks
381
Avg merge
17h 10m
Merged PRs (30d)
11

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from jwt/ruby-jwt

All issues in jwt/ruby-jwt

Similar issues

More Ruby issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.