Minimum ruby version?
futureperfect opened this issue · 7 comments
I was curious to know what minimum version of ruby you were targeting with this library. I noticed your use of url_safe_base64
might be related to attempting to support older rubies?
The reason I ask is that there's at least one corner case in decoding Base64-encoded data that is incorrectly handled in url_safe_base64
that I'd either like to address or remove the dependency on the library.
officially ruby 2.2.2 is the minimum, but I don't want to hardly break 2.1.0 support at current period.
btw, url_safe_base64 isn't for legacy ruby support.
BTW, what is the "corner case"?
Currently, I don't have any strong motivation to remove url_safe_base64
gem dependency.
There was some work released in ruby 2.3.0 to enhance URL-safe encoding.
https://github.com/ruby/ruby/pull/815/files
When adapting the added tests into url_safe_base64, they do not behave consistent with either ruby 2.3.0 or what RFC4648 or RFC 7515 suggest.
I also noticed in https://tools.ietf.org/html/rfc7515#appendix-C the note
if the length mod 4 is 1, the input is malformed.
If I'm reading the tests I've adapted correctly, this case is incorrectly treated as valid by url_safe_base64
and decoded.
I was curious before if it was a historical reason related to older ruby support that this library was introduced, because as it stands it does not appear to be a standards-conformant url-safe Base64 decoder.
2.2 support is still needed.
Plus, malformed base64 input shouldn't become valid jwt if it's integrity protected.
What about backporting the 4 functions from Base64
module in ruby-2.3.0 into its own class/module and jettisoning the incorrect version from your library dependency?
It also works.
I still do not think malformed base64 handling is important in jwt context though.
A note for anyone running Ruby 2.1:
json-jwt creates symbols (using #to_sym) from the 'alg' field at an early stage of JWS verification. For user supplied JWTs (which is almost always the case), this will create a memory leak (aka Symbol DoS) in the event of malicious JWTs.
@nov, I'd recommend formally adding Ruby 2.2 as a minimum version to the README along with a note that while 2.1 may function, it is at risk of a Symbol DoS.
Proof of concept (on Ruby 2.1) which basically generates JWTs with arbitrary values for 'alg' and then attempts to decode them:
[12] pry(main)> Symbol.all_symbols.size
=> 26631
[13] pry(main)> 10000.times{|n| j=JSON::JWT.new a: 1 ; j.alg = "#{n}" ; s=j.to_s ; (JSON::JWT.decode(s, 'some-key') rescue nil) }
=> 10000
[14] pry(main)> Symbol.all_symbols.size
=> 36631