Skip to content

[🐛 Bug]: Failing serialization of Credential (virtual authenticator) in Ruby #16916

@halo

Description

@halo

Description

I'm using Selenium::WebDriver::VirtualAuthenticator#credentials to retrieve an instance of Selenium::WebDriver::Credential.

I expect the private_key of that Credential instance to be an Array of bytes. But it is an encoded String.

I believe this is because Credential.from_json does not decode the private key.

When I change that line in Credential.from_json to private_key: decode(opts['privateKey']), everything works as I expect it.

Thank you for your time!

Reproducible Code

require 'selenium/webdriver'
driver = Selenium::WebDriver.for(:chrome)

# Setup (Create Authenticator)
options = ::Selenium::WebDriver::VirtualAuthenticatorOptions.new
authenticator = driver.add_virtual_authenticator(options)
credential = Selenium::WebDriver::Credential.new(
  id: [42],
  resident_credential: false,
  rp_id: 'example.com',
  private_key: [48, 129, 135, 2, 1, 0, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 4, 109, 48, 107, 2, 1, 1, 4, 32, 180, 15, 115, 184, 64, 136, 181, 242, 177, 253, 112, 119, 88, 51, 33, 119, 97, 93, 187, 200, 196, 19, 170, 66, 195, 72, 214, 205, 144, 50, 128, 14, 161, 68, 3, 66, 0, 4, 192, 92, 225, 160, 92, 154, 118, 240, 173, 205, 157, 199, 30, 96, 182, 106, 232, 23, 82, 13, 237, 214, 255, 10, 238, 92, 56, 30, 242, 102, 226, 80, 99, 52, 54, 71, 161, 207, 215, 229, 125, 30, 78, 149, 201, 94, 210, 43, 86, 100, 183, 237, 44, 114, 57, 233, 214, 128, 77, 232, 16, 46, 170, 131],
  sign_count: 1,
  user_handle: [97, 108, 105, 99, 101]
)

puts 'GOOD:'
puts credential.private_key.join # Array (correct)
puts credential.as_json['privateKey'] # String (correct)

# Add the credential to an Authenticator and read it out again
authenticator.add_credential(credential)
retrieved_credential = authenticator.credentials.first

puts 'BAD:'
puts retrieved_credential.private_key # This is a String!

# This tries to convert the byte Array to a String, but that can't work, because the private_key already is a String:
puts retrieved_credential.as_json

# Fails with
# .../selenium-webdriver-4.39.0/lib/selenium/webdriver/common/virtual_authenticator/credential.rb:38:in 'Selenium::WebDriver::Credential.encode': undefined method 'pack' for an instance of String (NoMethodError)
#           Base64.urlsafe_encode64(byte_array&.pack('C*'))
#                                             ^^^^^^
# Did you mean?  unpack
# 	from .../selenium-webdriver-4.39.0/lib/selenium/webdriver/common/virtual_authenticator/credential.rb:78:in 'Selenium::WebDriver::Credential#as_json'
# 	from .../selenium-webdriver-4.39.0/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb:38:in 'Selenium::WebDriver::VirtualAuthenticator#add_credential'
# 	from repro.rb:22:in '<main>'

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-needs-triagingA Selenium member will evaluate this soon!C-rbRuby BindingsD-chromeI-defectSomething is not working as intendedOS-mac

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions