Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppressing unexpected error with WebAuthn::PublicKeyCredentialWithAttestation#verify #413

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion lib/webauthn/public_key_credential.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

module WebAuthn
class PublicKeyCredential
class InvalidChallengeError < Error; end

attr_reader :type, :id, :raw_id, :client_extension_outputs, :authenticator_attachment, :response

def self.from_client(credential, relying_party: WebAuthn.configuration.relying_party)
Expand Down Expand Up @@ -36,7 +38,13 @@ def initialize(
@relying_party = relying_party
end

def verify(*_args)
def verify(challenge, *_args)
unless valid_class?(challenge)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just:

Suggested change
unless valid_class?(challenge)
unless challenge.is_a?(String)

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It follows the existing check processes valid_type? and valid_id?.
For example, valid_type? is a simple value comparison, but it is implemented as a private method.
Therefore, following the implementation of the entire class, we also extracted the method as valid_class? when checking the class this time.

However, as you suspected, I think it is also more readable to use is_a? in the verify method without extracting it to the method. If you need it, please let me know so I can move it.

msg = "challenge must be a String. input challenge class: #{challenge.class}"

raise(InvalidChallengeError, msg)
end

valid_type? || raise("invalid type")
valid_id? || raise("invalid id")

Expand Down Expand Up @@ -71,6 +79,10 @@ def valid_id?
raw_id && id && raw_id == WebAuthn.standard_encoder.decode(id)
end

def valid_class?(challenge)
challenge.is_a?(String)
end

def authenticator_data
response&.authenticator_data
end
Expand Down
12 changes: 12 additions & 0 deletions spec/webauthn/public_key_credential_with_assertion_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,18 @@
end
end

context "when challenge class is invalid" do
it "raise error" do
expect do
public_key_credential.verify(
nil,
public_key: credential_public_key,
sign_count: credential_sign_count
)
end.to raise_error(WebAuthn::PublicKeyCredential::InvalidChallengeError)
end
end

context "when challenge is invalid" do
let(:challenge) { Base64.urlsafe_encode64("another challenge") }

Expand Down
10 changes: 9 additions & 1 deletion spec/webauthn/public_key_credential_with_attestation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,15 @@
end
end

context "when challenge is invalid" do
context "when challenge class is invalid" do
it "raise error" do
expect {
public_key_credential.verify(nil)
}.to raise_error(WebAuthn::PublicKeyCredential::InvalidChallengeError)
end
end

context "when challenge value is invalid" do
it "fails" do
expect {
public_key_credential.verify(Base64.urlsafe_encode64("another challenge"))
Expand Down