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

Serial number #34

Open
JamesB7 opened this issue Oct 21, 2020 · 14 comments
Open

Serial number #34

JamesB7 opened this issue Oct 21, 2020 · 14 comments

Comments

@JamesB7
Copy link

JamesB7 commented Oct 21, 2020

Would you please make it so, after the page has access to the device, it can query the serial number? I would like to store user customizations based on serial number, and there is presently no way to do this.

Right now I am using WebUSB (where serial number is available), but WebHID would allow me to support our legacy products as well, so I would like to support it.

@nondebug
Copy link
Collaborator

Serial numbers are excluded for two reasons:

Privacy risk. Serial numbers are durable unique identifiers that can be used for precise fingerprinting. Exposing the serial number would allow a user to be tracked across the web by any site that has permission to access that device.

Consistency. The USB serial number is an optional USB-level attribute rather than a part of the HID protocol. Many USB HID devices do not expose a serial number, and non-USB HID devices do not have serial numbers at all.

I agree that it would be useful to expose something like a serial number for identifying devices that were previously connected, as well as distinguishing multiple instances of the same device.

To preserve privacy, I think this identifier should aim to fulfill these requirements:

  • The device identifier should be different when the same device is accessed from different origins
  • The device identifier should be different for different users on the same host machine
  • The device identifier should be different for the same user on a different host machine
  • It should be possible for a user to invalidate all previously-granted device identifiers by clearing site data

We can also try to provide an identifier for non-USB devices as well as USB devices that don't expose a serial number. This is possible because most systems assign an identifier that persists as long as the bus topology hasn't changed. For instance, Container ID on Windows and LocationID on macOS. These identifiers should remain constant across browser restarts, host reboots, and possibly device disconnection/reconnection as long as the device is reconnected to the same port.

@JamesB7
Copy link
Author

JamesB7 commented Oct 22, 2020

Yes, this sounds like a great idea. Here's some background to our particular needs, if it helps to provide context to what I'm asking.

Our HID firmware update (for example) reboots the device into a mode where its serial number is identical but with a bit flipped on the Product ID. (The descriptors differ in the bootloader.) It then proceeds with the second part of the update.

(EScribe at www.evolvapor.com / ECigStats at www.ecigstats.org are the software packages I am porting a bit of over to JavaScript, in case you are curious.)

Bus topology... for devices that are plugged in/unplugged often, they may be plugged into different hubs, etc. all the time.

By USB spec, if a serial number is provided it must be unique, so this can be used to determine if a device has already been paired. You could, if the serial number exists, HMAC it by a unique key generated for the site by the browser, unknown to the application, and resettable. If no serial number exists, by all means, fallback to something like Container ID. This would let the serial number be followed between different VID/PID, regardless of how the user has plugged it in.

I can't speak for anyone else, but for my use, a consistent identifier (say, HMACed serial number) would be workable if need be. I can see the privacy argument, especially for gamepads etc. where one would have no expectation of it being used for site-to-site tracking. That's fair. It would meet my needs at least, so long as it derives from serial number.

I have to ask though, isn't this issue the same as for WebUSB? If you want to go this route, you should do the same there too. If 'serialNumber' became a HMACed serial number, I don't think it would break anyone's code (if a company is using non-unique serials for some other purpose, they are already against the USB spec). It would provide more privacy there too.

@nondebug
Copy link
Collaborator

Our HID firmware update (for example) reboots the device into a mode where its serial number is identical but with a bit flipped on the Product ID. (The descriptors differ in the bootloader.) It then proceeds with the second part of the update.

If the product ID is changed then the browser will consider it a different device and the firmware update application will need to ask the user to grant access again. I think this negates most of the benefit from being able to re-identify the device by its serial number.

Bus topology... for devices that are plugged in/unplugged often, they may be plugged into different hubs, etc. all the time.

Agreed, using Container ID or LocationID would be a fallback for devices that have no other unique identifier. I'm considering three classes of devices:

  • Devices that expose a unique, stable identifier (ex: USB serial number, Bluetooth device address)
  • Devices that do not expose a unique, stable identifier, but can be identified by an identifier that is stable while the device remains connected to the host (ex: USB device without serial number, I2C HID devices)
  • Devices that do not expose any identifying information, or the information is not usable or cannot be trusted (ex: userspace HID devices, virtual HID devices)

In the first case, for a USB device with a serial number we can tie the identifier to a combination of (origin URL, serial number, vendor ID, product ID, user profile salt). In the second case, a USB device without a serial number would tie the identifier to (origin URL, container ID, vendor ID, product ID, user profile salt). Instead of exposing a hash, I expect we would generate a random GUID and store the device details internally with the GUID as the key. In the third case we would generate a new random GUID each time the device is connected and tie it to (origin URL, Container ID, user profile salt).

This would let the serial number be followed between different VID/PID, regardless of how the user has plugged it in.

I don't think we can support this use case since there's no guarantee that a serial number is unique except potentially within a vendor's own product line.

I have to ask though, isn't this issue the same as for WebUSB? If you want to go this route, you should do the same there too.

The current best practice for mitigating fingerprinting says to "Limit permanent or persistent state" which would apply to the USB serial number string since it is typically baked into a device's firmware without any way for the user to modify it. I think there's a decent argument that exposing the actual USB serial number is necessary for reasons similar to the ones you've given, despite the privacy concerns. I would be in favor of adding the new ID alongside the serial number if it's not possible to replace it without breaking applications. Relevant issue: WICG/webusb#23

I would also like to see this ID added to other device APIs like Gamepad and Serial.

We are thinking about how to integrate WebUSB with other device APIs as a way to simplify permissions management. Currently, if an app wants to access WebHID and WebUSB functionality on the same USB device it needs to show two different permission prompts. This is confusing since a device's use of the HID protocol is an implementation detail that is not advertised to users. It would be simpler if the permission prompt were tied to the device itself rather than a particular protocol so that granting permission for a device grants access to all relevant device APIs. I would prefer this route over including the USB-specific properties in the WebHID API. Relevant issue: WICG/webusb#186

@JamesB7
Copy link
Author

JamesB7 commented Oct 22, 2020

Yes, a new permission dialog is needed, and in this case we can filter it safely to a single device.

WebUSB is not accessible unless there is a WinUSB endpoint -- USB properties are important to HID devices as well, and if WebUSB is available, there is no reason to use WebHID. Many devices (such as ours) use HID for driverless install, but are otherwise ordinary USB devices.

A serial number may not be unique, but it is extremely likely to be, and a HMACed serial provides the same semantics as a normal serial number.

@yoichiro
Copy link

This is a great proposal and discussion. I also think that we need some ID to identify some devices which are same model. Of course, the serial number is most suitable, but, yeah, I know that there is a privacy issue against the serial number. I guess that GUID issued by the user agent is very usable.

@todbot
Copy link

todbot commented Mar 23, 2021

Could the serial number be locally hashed to allow identification on a single host? There are some HID devices where multiples are in use on a single system. One concrete example is the blink(1) USB LED. Current native HID libraries use serial number to allow customers to disambiguate devices and assign them different roles. This use of the serial numbers here is purely to identify this devices from that device, not for personally-identifiable info.

@thegecko
Copy link

thegecko commented Apr 3, 2021

I would like to chime in and say that this would also be a great addition to have a unique identifier on a HID device in the specification.

There are a few real-world use cases for this we have today:

  • It's very common to have multiple devices attached to the system with the same VID/PID (see Mbed devices which are all the same). This makes it impossible to work with multiple devices and keep track of them.

  • State management. Extra state for a device (e.g. a unique name shown to the user) could be stored separately. Without a unique reference to the device when plugged in, this can't be guaranteed to be applied to the correct device.

  • Most importantly is the need for a reference for a device to go across logical boundaries. We have a use case where we undertake heavy USB access (currently using WebUSB) from within a webworker, but the device needs to be selected in the main UI thread.
    Therefore we use serialNumber to reacquire access to the device in the webworker as you cannot pass the device between the contexts. The same is true for protocols such as the Debug Adapter Protocol. To model this in WebHID, you'd save the unique identifier in the main thread, then use getDevices() in the other context and filter by the identifier.

A strong reason for the unique identifier to be serialNumber is to allow soft links between devices using Web-* connections (WebUSB, WebSerial, WebHID, etc.). For example, if a user has already selected a WebHID device, the serialNumber from it could be used to filter a further selection for WebUSB access with navigator.usb.requestDevice().
If serialNumber is also exposed in HIDDeviceFilter, the opposite would also be possible.

Are security concerns with WebHID and serialNumber greater than in WebUSB which exposes this? It would be good to see some consistency between these specifications.

...and if WebUSB is available, there is no reason to use WebHID

I disagree, WebUSB requires vendor class endpoints (0xFF) which in some cases means rewriting firmware and legacy hardware 'in the field' can only be accessed using WebHID.

Please see WICG/serial#128 (comment) for an identical issue raised for WebSerial

@JamesB7
Copy link
Author

JamesB7 commented May 19, 2021

WebBluetooth provides an 'id' which is origin specific and can be used to differentiate multiple devices.
This would go a LONG way.

A privacy protecting (say, by HMAC) serial number is something different. It would be very helpful, and if done by HMAC would preserve the semantics of a serial number. But really, on reflection, it's a different discussion.

The most important thing is a unique ID to differentiate connected HID devices. Right now, if you have two, you can't store settings etc.

@petterhanssen
Copy link

Any ETA on this? We have implemented BusyLight (https://busylight.com/) in our web application by using WebHID, but are not able to persist device access due to missing serial number on the device.

GUID based on origin URL, container ID, vendor ID, product ID, user profile salt would be a perfect fit for our use case.

@JamesB7
Copy link
Author

JamesB7 commented Jan 11, 2022

Any word on this? I really need it to make a proper port of my software ( https://www.evolvapor.com/escribe , https://www.dimensionengineering.com/describe ) to web.

Not being able to distinguish or remember different devices is a problem for autoconnect, for firmware updates (where I need to open/close the connection multiple times), for handoff between different components, etc. We also store settings, such as customized graphs, by device. We have one WebUSB device coming out soon, but everything we've made so far is pure HID for wide compatibility.

@harlankoehn
Copy link

harlankoehn commented May 19, 2022

I'm also interested in this issue. The only way I can see making it secure would be to allow the browser/client to request unique id generation for a specific device or for all WebHID devices, passing along a salt that the client application would be responsible for generating and persisting across sessions, and using each time it requests unique ID's for devices. In this case the browser would generate and return a cryptographic hash based on serial number, vendor id, product id, domain, and salt.

@william-s-owen
Copy link

The lack of serial number is an issue for my device/implementation as well. Lack of indexed string descriptors in general is problematic (unless I am missing something).

@troman29
Copy link

We also need to distinguish between several identical devices. I also think that a single identifier on several sites is not so bad, since I rarely provide access to the same device and do it consciously. Sites do not have access by default. Any solution will do.

@taf2
Copy link

taf2 commented Aug 21, 2023

This would enable a lot of very useful applications that otherwise require a desktop application...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
10 participants