CVE-2019-18848: Improper Authentication (CWE-287)
value: The json-jwt gem before 1.11.0 for Ruby lacks an element count during the splitting of a JWE string.
CWE description: When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
CVSS v3 base score: 7.5
Published: 2019-11-12T15:15Z
Repository: https://github.com/nov/json-jwt
Language: Ruby
Files changed: lib/json/jwe.rb, lib/json/jws.rb
Commit date: 2019-11-11 23:28:48 +0900
Commit message: explicitly specifying number of elements when splitting JWE string

ref.) CVE-2019-18848

Diff: diff --git a/lib/json/jwe.rb b/lib/json/jwe.rb
index f5a4919..03cfd3a 100644
--- a/lib/json/jwe.rb
+++ b/lib/json/jwe.rb
@@ -252,11 +252,11 @@ module JSON
       def decode_compact_serialized(input, private_key_or_secret, algorithms = nil, encryption_methods = nil, _allow_blank_payload = false)
         unless input.count('.') + 1 == NUM_OF_SEGMENTS
           raise InvalidFormat.new("Invalid JWE Format. JWE should include #{NUM_OF_SEGMENTS} segments.")
         end
         jwe = new
-        _header_json_, jwe.jwe_encrypted_key, jwe.iv, jwe.cipher_text, jwe.authentication_tag = input.split('.').collect do |segment|
+        _header_json_, jwe.jwe_encrypted_key, jwe.iv, jwe.cipher_text, jwe.authentication_tag = input.split('.', NUM_OF_SEGMENTS).collect do |segment|
           begin
             Base64.urlsafe_decode64 segment
           rescue ArgumentError
             raise DecryptionFailed
           end
diff --git a/lib/json/jws.rb b/lib/json/jws.rb
index a97a4a3..826416c 100644
--- a/lib/json/jws.rb
+++ b/lib/json/jws.rb
@@ -177,11 +177,11 @@ module JSON
     class << self
       def decode_compact_serialized(input, public_key_or_secret, algorithms = nil, allow_blank_payload = false)
         unless input.count('.') + 1 == NUM_OF_SEGMENTS
           raise InvalidFormat.new("Invalid JWS Format. JWS should include #{NUM_OF_SEGMENTS} segments.")
         end
-        header, claims, signature = input.split('.', JWS::NUM_OF_SEGMENTS).collect do |segment|
+        header, claims, signature = input.split('.', NUM_OF_SEGMENTS).collect do |segment|
           Base64.urlsafe_decode64 segment.to_s
         end
         header = JSON.parse(header).with_indifferent_access
         if allow_blank_payload && claims == ''
           claims = nil
@@ -189,11 +189,11 @@ module JSON
           claims = JSON.parse(claims).with_indifferent_access
         end
         jws = new claims
         jws.header = header
         jws.signature = signature
-        jws.signature_base_string = input.split('.')[0, JWS::NUM_OF_SEGMENTS - 1].join('.')
+        jws.signature_base_string = input.split('.')[0, NUM_OF_SEGMENTS - 1].join('.')
         jws.verify! public_key_or_secret, algorithms unless public_key_or_secret == :skip_verification
         jws
       end
 
       def decode_json_serialized(input, public_key_or_secret, algorithms = nil, allow_blank_payload = false)

Vulnerable code:         _header_json_, jwe.jwe_encrypted_key, jwe.iv, jwe.cipher_text, jwe.authentication_tag = input.split('.').collect do |segment|
        header, claims, signature = input.split('.', JWS::NUM_OF_SEGMENTS).collect do |segment|
        jws.signature_base_string = input.split('.')[0, JWS::NUM_OF_SEGMENTS - 1].join('.')
Fixed code:         _header_json_, jwe.jwe_encrypted_key, jwe.iv, jwe.cipher_text, jwe.authentication_tag = input.split('.', NUM_OF_SEGMENTS).collect do |segment|
        header, claims, signature = input.split('.', NUM_OF_SEGMENTS).collect do |segment|
        jws.signature_base_string = input.split('.')[0, NUM_OF_SEGMENTS - 1].join('.')