Skip to content

Commit

Permalink
Drop use of base64 gem and warn about invalid base64 input
Browse files Browse the repository at this point in the history
  • Loading branch information
anakinj committed Dec 30, 2023
1 parent 7c61cf4 commit 001cba6
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
- Fix key base equality and spaceship operators [#569](https://github.com/jwt/ruby-jwt/pull/569) - [@magneland](https://github.com/magneland).
- Remove explicit base64 require from x5c_key_finder [#580](https://github.com/jwt/ruby-jwt/pull/580) - [@anakinj](https://github.com/anakinj).
- Performance improvements and cleanup of tests [#581](https://github.com/jwt/ruby-jwt/pull/581) - [@anakinj](https://github.com/anakinj).
- Drop dependency to base64 gem [#578](https://github.com/jwt/ruby-jwt/pull/578) - [@anakinj](https://github.com/anakinj).
- Deprecation warning for decoding content not compliant with RFC 4648 [#578](https://github.com/jwt/ruby-jwt/pull/578) - [@anakinj](https://github.com/anakinj).
- Your contribution here

## [v2.7.1](https://github.com/jwt/ruby-jwt/tree/v2.8.0) (2023-06-09)
Expand Down
26 changes: 20 additions & 6 deletions lib/jwt/base64.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
# frozen_string_literal: true

require 'base64'

module JWT
# Base64 helpers
# Base64 encoding and decoding
class Base64
class << self
# Encode a string with URL-safe Base64 complying with RFC 4648 (not padded).
def url_encode(str)
::Base64.encode64(str).tr('+/', '-_').gsub(/[\n=]/, '')
encoded = [str].pack('m0')
encoded.chomp!('==') || encoded.chomp!('=')
encoded.tr!('+/', '-_')
encoded
end

# Decode a string with URL-safe Base64 complying with RFC 4648.
# Deprecated support for RFC 2045 remains for now. ("All line breaks or other characters not found in Table 1 must be ignored by decoding software")
def url_decode(str)
str += '=' * (4 - str.length.modulo(4))
::Base64.decode64(str.tr('-_', '+/'))
if !str.end_with?('=') && str.length % 4 != 0
str = str.ljust((str.length + 3) & ~3, '=')
str.tr!('-_', '+/')
else
str = str.tr('-_', '+/')
end
str.unpack1('m0')
rescue ArgumentError => e
raise unless e.message == 'invalid base64'

warn('[DEPRECATION] Invalid base64 input detected, could be because of invalid padding, trailing whitespaces or newline chars. Graceful handling of invalid input will be dropped in the next major version of ruby-jwt')
str.unpack1('m')
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/jwt/x5c_key_finder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

let(:crl) { issue_crl([], issuer: root_certificate, issuer_key: root_key) }

let(:x5c_header) { [Base64.strict_encode64(leaf_certificate.to_der)] }
let(:x5c_header) { [JWT::Base64.encode64(leaf_certificate.to_der)] }
subject(:keyfinder) { described_class.new([root_certificate], [crl]).from(x5c_header) }

it 'returns the public key from a certificate that is signed by trusted roots and not revoked' do
Expand Down

0 comments on commit 001cba6

Please sign in to comment.