So I know of a very popular keyboard controller than can be made to run unsigned code by sending it the right HID data.
Said code persists after reboot.
Please point out if this attack is not viable:
Ask for permission to use your keyboard. No matter how scary the warning, non-technical users will allow a website to use the keyboard because "of course it needs a keyboard"
Upload a malicious payload to keyboard. Remember, now it can present itself as any USB device. Or maybe stay simple with a keylogger, maybe with heuristics to get juicy data (what are the first 20 characters typed at boot and after "www" is typed)
(And yes I read the section 3 of the standard before writing the comment above, see my other comment in this thread)
WebHID even says it more plainly:
> In general, these types of attacks are device-specific and cannot be mitigated at the API level.
Both documents you linked literally go:
"We know these attacks exist, we don't care as long as we show a prompt, device manufacturers fix your shit it's not our problem"
-
I can't reply for some reason but:
I didn't see any mention of HID devices not being listed, not was it immediately apparent that a HID device would already be held in the kernel context
I also still don't see blocking input from trusted devices, I see the same language I called out:
"Device manufacturers should watch out"
-
"I think it works like this, why doesn't it" is a great way to learn things, except when the reply is a low effort: "here's that thing you read, did you actually read it?"
Going with the good faith assumption you read it trying to find why instead of why not in the WebUSB standard you can find this paragraph under 3.1 Abusing Access to a Device:
"Lastly, since USB devices are unable to distinguish requests from multiple sources, operating systems only allow a USB interface to have a single owning user-space or kernel-space driver. The UA acts as a user-space driver, therefore allowing only a single execution context to claim a USB interface at a time. The claimInterface() function will fail if multiple execution contexts attempt to claim an interface."
I.e. the keyboard couldn't be claimed even if you managed to get it to list as it's claimed via the OS HID driver so can't be claimed via the userspace driver. HID devices are also hid from the listing (no pun intendend) which is what resulted in the WebHID standard in the first place.
For WebHID understand it's an early draft and that the method described in section 3.1 of blocking access to HID devices that can generate trusted input is actually the go forward implementation plan not merely a suggestion.
.
I don't mind discussing WebUSB further but not if the conversation is just going to be in a "I thought it might work this way, show me the line that says it isn't" way. There are many blog posts that cover it better than I could anyways (such as https://blog.scottlogic.com/2019/04/03/upcoming-webhid-api.h...)
Just to clarify I'm no expert in USB in any way, shape, or form and do not wish to claim to be. I have never worked with USB (beyond quite literally sticking a device in the port or reading about which USB storage drive to get) prior to reading the original article this post linked to and don't want to give the false impression I'm an expert in the field because I've read a few documents/demos followed by a couple of blog posts after.
I didn't see any mention of HID devices not being listed, not was it immediately apparent that a HID device would already be held in the kernel context
I also still don't see blocking input from trusted devices, I see the same language I called out:
"Device manufacturers should watch out"
-
"I think it works like this, why doesn't it" is a great way to learn things, except when the reply is a low effort: "here's that thing you read, did you actually read it?"
Also I'm pretty sure the parent's point is jumping from "the kernel and userspace are not allowed to both access a device" to "keyboards cannot be accessed" is non-obvious
I still don't see where the filter on HID devices is mentioned, or the exception for trusted devices
Note on reply disappearing: I think sometimes HN hides the reply unless you go to the permalink (i.e. what the "2 minutes ago" link points to). Or at least that's how I work around it when I don't see the reply button. Not really sure why it does that, never looked into it.
It's not so much about the HID class itself as "why" (it's more an effect you find out later once you know what the HID class is) as it is "if an OS driver doesn't already hold the USB keyboard how could you type on it". The opening paragraph of the standard tips this off straight away:
"...Standard device classes include keyboard, mice, audio, video and storage devices. Operating systems support such devices using the "class driver" provided by the OS vendor..."
That combined with the closing paragraph of 3.1 under security considerations I quoted before led to the answer for the particular question without the explicit mention of "HID" in the document:
"Lastly, since USB devices are unable to distinguish requests from multiple sources, operating systems only allow a USB interface to have a single owning user-space or kernel-space driver. The UA acts as a user-space driver, therefore allowing only a single execution context to claim a USB interface at a time. The claimInterface() function will fail if multiple execution contexts attempt to claim an interface."
I later ran across "HID" reading a blog post while testing some code which is how I fumbled to finding WebHID. For the WebHID portion the hint I originally mentioned came from this paragraph in 3.1:
"In some cases, a device may expose functionality that should not be accessible at all from a web page. Specific devices may be blocked by recognizing the device by its vendor and product ID and hiding such devices during enumeration. The HID report descriptor allows a device to describe its own capabilities, and this information can be used to block classes of devices even when the vendor and product ID cannot be known in advance. This can be accomplished by inspecting the usage values assigned to collections within the report descriptor; for instance, access to keyboard-like devices can be denied by denying access to devices that include a top-level collection with the Keyboard usage ID."
I guess "mitigates" wasn't fair as the feature still hasn't even had an experimental implementation added behind a flag in Chrome yet let alone have a demonstrable implementation of the proposed protection. I'd say "considered" was fair though and not at all hidden/hard to find.
I also wanted to point out that the wording around "manufacturers should do" in both is presented an argument for defense in depth (IIRC they even called out defense in depth explicit in one of the calls to action) not their argument for "since manufacturers should do this we shouldn't do anything". Again about reading to find "why" vs "why not" which usually requires reading in context instead of searching for a key phrase.
.
Don't get me wrong, questions are a fine method of learning! It's just your initial question was "Please point out if this attack is not viable" not an ask of "I saw this in the standard, can you explain why this attack is not viable?" so I told you it's not viable and then mentioned it's in the first 3 sections in case you were curious. The response I got back was that you had already read section 3 and got a different takeaway. Well of course you did, I didn't say why was in section 3 I said it was in the first 3 sections, which are quicker reads than the comment chain the question came from! Going on good faith I pulled the exact quote out, explained it further, and then mentioned "I thought it might work this way, show me the line that says it isn't" isn't how I want to talk about the standard to then get told my original comment which answered exactly what you asked was low effort! Looking back I can see the confusion with section 3/first 3 sections and that originally you very likely meant "could you explain why" not a literal "is it or not" so my apologies for misinterpreting where you were trying to drive the conversation but I ask you consider the above as well before judging my reply/cautiousness to be just low effort/dismissive.
Anyways I hope the content above the "." gets us on the same page. I'd have shared some modified WICG/webusb GitHub repo linked demos I worked on earlier to validate my understanding before I said "nope" but they don't work on JSFiddle/CodePen because WebUSB requires a feature-policy header to be set to be used in a page + "allow" to an iframe (which seems like other great protections but absolute pains for testing!) so you'll just have to take my word on the real world test :).