Skip to content

[core] Set ruby-jwt gem to v2.10.3 minimum. #30056

Merged
iBotPeaches merged 2 commits into
fastlane:masterfrom
nakshatrasinghh:30055-fix-jwt-security-floor
Jun 1, 2026
Merged

[core] Set ruby-jwt gem to v2.10.3 minimum. #30056
iBotPeaches merged 2 commits into
fastlane:masterfrom
nakshatrasinghh:30055-fix-jwt-security-floor

Conversation

@nakshatrasinghh

@nakshatrasinghh nakshatrasinghh commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Checklist

  • I've run bundle exec rspec from the root directory to see all new and existing tests pass
  • I've followed the fastlane code style and run bundle exec rubocop -a to ensure the code style is valid
  • I see several green ci/circleci builds in the "All checks have passed" section of my PR (connect CircleCI to GitHub if not)
  • I've read the Contribution Guidelines
  • I've updated the documentation if necessary.
  • I've added or updated relevant unit tests.

Motivation and Context

Resolves #30055

ruby-jwt versions before the patched releases allow an empty HMAC key to verify attacker-crafted HS256 tokens when callers decode with an empty string key or a keyfinder that returns an empty string.

fastlane already widened the upper jwt dependency bound to allow the v3 series, but the lower bound still allowed vulnerable 2.x versions. During investigation, I confirmed that the fix was backported to jwt 2.10.3, so fastlane can require a patched version without forcing all users onto the v3 dependency path.

This keeps fastlane compatible with its current Ruby >= 3.0 minimum while still allowing safe jwt 3.2.0+ versions.

Description

This PR tightens fastlane's jwt dependency requirement to patched versions only.

The change:

  • raises the minimum jwt version to 2.10.3
  • excludes vulnerable jwt 3.0.0 through 3.1.2
  • updates Gemfile.lock to resolve jwt 2.10.3
  • adds a gemspec regression spec to ensure vulnerable versions are not accepted by the dependency requirement

I investigated the reported behavior by reproducing the empty-key HMAC verification with an affected jwt version, then verified that the updated dependency resolves to jwt 2.10.3 and rejects both the static empty-key and keyfinder empty-key cases.

Documentation was not changed because this is a dependency/security constraint update rather than a user-facing fastlane feature or configuration change.

Testing Steps

Reproduced the vulnerable behavior with an affected jwt version:

  • crafted an HS256 token signed with an empty HMAC key
  • verified that affected jwt accepted the token with both a static empty string key and a keyfinder returning ""

Verified the fixed behavior with the updated bundle:

  • confirmed the bundle resolves to jwt 2.10.3
  • confirmed the crafted empty-key token is rejected with JWT::DecodeError: HMAC key cannot be empty
  • confirmed App Store Connect ES256 token generation still works

@nakshatrasinghh nakshatrasinghh force-pushed the 30055-fix-jwt-security-floor branch from 5a31165 to 8422b7c Compare June 1, 2026 16:44
@iBotPeaches

Copy link
Copy Markdown
Member

Thanks! - this is a bit too much.

I only want to track exclusions for urgent issues that are breaking, like we did on openssl when literally anything HTTPS failed. That is breaking to fastlane and thus we exclude that version.

These versions are excluded for security reasons it seems and may introduce complexities for other orgs. Lets only move our minimum to 2.x and kill the test. Its too hooked to a specific line of code and doesn't really test anything outside of that.

@nakshatrasinghh

Copy link
Copy Markdown
Contributor Author

Alright, that makes sense.

I simplified this to only raise the minimum jwt version to 2.10.3, removed the explicit 3.x exclusions, and removed the gemspec spec since it was only testing the dependency declaration itself.

One small thing I would want to point out: this keeps the PR aligned with fastlane’s usual dependency policy and avoids extra constraints, but it does mean we are no longer blocking the affected 3.x releases at the fastlane dependency boundary. In practice, fastlane’s current bundle still resolves to jwt 2.10.3 because of the existing googleauth / signet < 3.0 constraints, so the reported case is still fixed here.

I re-verified that the bundle resolves to jwt 2.10.3, and the original empty-HMAC key reproduction is rejected with HMAC key cannot be empty.

@iBotPeaches iBotPeaches changed the title [core] Fix ruby-jwt empty-key HMAC dependency range [core] Set ruby-jwt gem to v2.10.3 minimum. Jun 1, 2026
@iBotPeaches iBotPeaches merged commit c30e449 into fastlane:master Jun 1, 2026
9 checks passed

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @nakshatrasinghh 👋

Thank you for your contribution to fastlane and congrats on getting this pull request merged 🎉
The code change now lives in the master branch, however it wasn't released to RubyGems yet.
We usually ship about once a month, and your PR will be included in the next one.

Please let us know if this change requires an immediate release by adding a comment here 👍
We'll notify you once we shipped a new release with your changes 🚀"

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulations! 🎉 This was released as part of fastlane 2.236.0 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ruby-jwt: Empty-key HMAC bypass; cross-language sibling of CVE-2026-44351

2 participants