diff --git a/lib/jwt.rb b/lib/jwt.rb index 6c15368b..ff1211ef 100644 --- a/lib/jwt.rb +++ b/lib/jwt.rb @@ -68,10 +68,13 @@ def decode(jwt, key=nil, verify=true, &keyfinder) begin header = MultiJson.decode(base64url_decode(header_segment)) payload = MultiJson.decode(base64url_decode(payload_segment)) - signature = base64url_decode(crypto_segment) if verify + signature = base64url_decode(crypto_segment.to_s) if verify rescue MultiJson::LoadError => e raise JWT::DecodeError.new("Invalid segment encoding") end + + raise JWT::DecodeError.new("Not enough or too many segments") unless header && payload + if verify algo = header["alg"] diff --git a/spec/jwt_spec.rb b/spec/jwt_spec.rb index b40faeb9..981bd672 100644 --- a/spec/jwt_spec.rb +++ b/spec/jwt_spec.rb @@ -58,6 +58,21 @@ lambda { JWT.decode(jwt, bad_private_key.public_key) }.should raise_error(JWT::DecodeError) end + it "raises exception with invalid signature" do + example_payload = {"hello" => "world"} + example_secret = 'secret' + example_jwt = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJoZWxsbyI6ICJ3b3JsZCJ9.' + lambda { JWT.decode(example_jwt, example_secret) }.should raise_error(JWT::DecodeError) + end + + it "raises exception with nonexistent header" do + lambda { JWT.decode("..stuff") }.should raise_error(JWT::DecodeError) + end + + it "raises exception with nonexistent payload" do + lambda { JWT.decode("eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9..stuff") }.should raise_error(JWT::DecodeError) + end + it "allows decoding without key" do right_secret = 'foo' bad_secret = 'bar' @@ -93,7 +108,7 @@ signature = JWT.base64url_decode(crypto_segment) signature.should_not_receive('==') JWT.should_receive(:base64url_decode).with(crypto_segment).once.and_return(signature) - JWT.should_receive(:base64url_decode).any_number_of_times.and_call_original + JWT.should_receive(:base64url_decode).at_least(:once).and_call_original JWT.decode(jwt, secret) end