diff --git a/lib/jwt.rb b/lib/jwt.rb index e8b86c6d..57457b63 100644 --- a/lib/jwt.rb +++ b/lib/jwt.rb @@ -41,8 +41,8 @@ def decode(jwt, key = nil, verify = true, custom_options = {}, &keyfinder) def decode_verify_signature(key, header, payload, signature, signing_input, options, &keyfinder) algo, key = signature_algorithm_and_key(header, payload, key, &keyfinder) - raise(JWT::IncorrectAlgorithm, 'An algorithm must be specified') unless options[:algorithm] - raise(JWT::IncorrectAlgorithm, 'Expected a different algorithm') unless algo == options[:algorithm] + raise(JWT::IncorrectAlgorithm, 'An algorithm must be specified') if allowed_algorithms(options).empty? + raise(JWT::IncorrectAlgorithm, 'Expected a different algorithm') unless allowed_algorithms(options).include?(algo) Signature.verify(algo, key, signing_input, signature) end @@ -58,4 +58,12 @@ def signature_algorithm_and_key(header, payload, key, &keyfinder) end [header['alg'], key] end + + def allowed_algorithms(options) + if options.key?(:algorithm) + [options[:algorithm]] + else + options[:algorithms] || [] + end + end end diff --git a/lib/jwt/default_options.rb b/lib/jwt/default_options.rb index 422a613e..0cf0e3de 100644 --- a/lib/jwt/default_options.rb +++ b/lib/jwt/default_options.rb @@ -9,7 +9,7 @@ module DefaultOptions verify_aud: false, verify_sub: false, leeway: 0, - algorithm: 'HS256' + algorithms: ['HS256'] }.freeze end end diff --git a/spec/jwt_spec.rb b/spec/jwt_spec.rb index 69b3477b..fbade515 100644 --- a/spec/jwt_spec.rb +++ b/spec/jwt_spec.rb @@ -231,15 +231,27 @@ context 'Verify' do context 'algorithm' do - it 'should raise JWT::IncorrectAlgorithm on missmatch' do - token = JWT.encode payload, data[:secret], 'HS512' + it 'should raise JWT::IncorrectAlgorithm on mismatch' do + token = JWT.encode payload, data[:secret], 'HS256' expect do JWT.decode token, data[:secret], true, algorithm: 'HS384' end.to raise_error JWT::IncorrectAlgorithm expect do - JWT.decode token, data[:secret], true, algorithm: 'HS512' + JWT.decode token, data[:secret], true, algorithm: 'HS256' + end.not_to raise_error + end + + it 'should raise JWT::IncorrectAlgorithm when algorithms array does not contain algorithm' do + token = JWT.encode payload, data[:secret], 'HS512' + + expect do + JWT.decode token, data[:secret], true, algorithms: ['HS384'] + end.to raise_error JWT::IncorrectAlgorithm + + expect do + JWT.decode token, data[:secret], true, algorithms: ['HS512', 'HS384'] end.not_to raise_error end