Skip to content

Commit

Permalink
FIX: Catch error when unknown COSE algorithm is supplied for Security…
Browse files Browse the repository at this point in the history
… Key (#8649)

Added a fix to gracefully error with a Webauthn::SecurityKeyError if somehow a user provides an unkown COSE algorithm when logging in with a security key.

If `COSE::Algorithm.find` returns nil we now fail gracefully and log the algorithm used along with the user ID and the security key params for debugging, as this will help us find other common algorithms to implement for webauthn
  • Loading branch information
martin-brennan committed Jan 2, 2020
1 parent 57081ac commit c031434
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
1 change: 1 addition & 0 deletions config/locales/server.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,7 @@ en:
public_key_error: "The public key verification for the credential failed."
ownership_error: "The security key is not owned by the user."
not_found_error: "A security key with the provided credential ID could not be found."
unknown_cose_algorithm_error: "The algorithm used for the security key is not recognized."

topic_flag_types:
spam:
Expand Down
1 change: 1 addition & 0 deletions lib/webauthn.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ class MalformedAttestationError < SecurityKeyError; end
class NotFoundError < SecurityKeyError; end
class OwnershipError < SecurityKeyError; end
class PublicKeyError < SecurityKeyError; end
class UnknownCOSEAlgorithmError < SecurityKeyError; end
end
9 changes: 8 additions & 1 deletion lib/webauthn/security_key_authentication_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,14 @@ def authenticate_security_key

# 17. Using credentialPublicKey, verify that sig is a valid signature over the binary concatenation of authData and hash.
cose_key = COSE::Key.deserialize(Base64.decode64(security_key.public_key))
if !cose_key.to_pkey.verify(COSE::Algorithm.find(cose_key.alg).hash_function, signature, auth_data + client_data_hash)
cose_algorithm = COSE::Algorithm.find(cose_key.alg)

if cose_algorithm.blank?
Rails.logger.error("Unknown COSE algorithm encountered. alg: #{cose_key.alg}. user_id: #{@current_user.id}. params: #{@params.inspect}")
raise(UnknownCOSEAlgorithmError, I18n.t('webauthn.validation.unknown_cose_algorithm_error'))
end

if !cose_key.to_pkey.verify(cose_algorithm.hash_function, signature, auth_data + client_data_hash)
raise(PublicKeyError, I18n.t('webauthn.validation.public_key_error'))
end

Expand Down
12 changes: 12 additions & 0 deletions spec/lib/webauthn/security_key_authentication_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,16 @@
)
end
end

context 'when the COSE algorithm used cannot be found' do
before do
COSE::Algorithm.expects(:find).returns(nil)
end

it 'raises a UnknownCOSEAlgorithmError' do
expect { subject.authenticate_security_key }.to raise_error(
Webauthn::UnknownCOSEAlgorithmError, I18n.t('webauthn.validation.unknown_cose_algorithm_error')
)
end
end
end

0 comments on commit c031434

Please sign in to comment.