WICG / webhid

Web API for accessing Human Interface Devices (HID)
Other
142 stars 35 forks source link

Consider relaxing keyboard blocklist rule to support vendor-specific behaviors #95

Open nondebug opened 2 years ago

nondebug commented 2 years ago

The blocklist rule for excluding HID keyboards currently blocks all reports in any collection with the Generic Desktop > Keyboard usage.

{usagePage:0x0001, usage:0x0006},  // Generic Desktop / Keyboard

This is perhaps overly broad since the HID specification only defines input and output reports for keyboards. The purpose of this rule is to mitigate the risk of input logging. For most keyboards, it's sufficient to block the input and output reports. (Input reports contain keystroke info and must be blocked. Output reports set the keyboard's LEDs and should also be blocked since the LEDs are typically set in response to keystrokes.) Feature reports, if present at all, are typically used for vendor-specific functionality.

It's recommended for vendors to place vendor-specific functionality in a separate top-level collection from the standard HID keyboard functionality to make it easier for applications to separate the sensitive keystroke data from vendor-proprietary reports. However, some devices include vendor functionality in the same top-level collection. For instance pcProx RFID card readers use the Generic Desktop > Keyboard usage and implement standard HID keyboard input and output reports alongside a vendor-specific feature report.

pcProx RFID badge reader (0C27:3BFA)

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x06,        // Usage (Keyboard)
0xA1, 0x01,        // Collection (Application)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0xE0,        //   Usage Minimum (0xE0)
0x29, 0xE7,        //   Usage Maximum (0xE7)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x08,        //   Report Count (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01,        //   Report Count (1)
0x75, 0x08,        //   Report Size (8)
0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x05,        //   Report Count (5)
0x75, 0x01,        //   Report Size (1)
0x05, 0x08,        //   Usage Page (LEDs)
0x19, 0x01,        //   Usage Minimum (Num Lock)
0x29, 0x05,        //   Usage Maximum (Kana)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x01,        //   Report Count (1)
0x75, 0x03,        //   Report Size (3)
0x91, 0x03,        //   Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x06,        //   Report Count (6)
0x75, 0x08,        //   Report Size (8)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x65,        //   Logical Maximum (101)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0x00,        //   Usage Minimum (0x00)
0x29, 0x65,        //   Usage Maximum (0x65)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0xA0,        //   Usage (0xA0)
0x15, 0x80,        //   Logical Minimum (-128)
0x25, 0x7F,        //   Logical Maximum (127)
0x75, 0x08,        //   Report Size (8)
0x95, 0x08,        //   Report Count (8)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 75 bytes

In order to enable support for pcProx RFID card readers and other keyboard-like devices with vendor-specific functionality implemented in a feature report, we can consider relaxing the rule to only block input and output reports and allow feature reports to be used normally:

{usagePage:0x0001, usage:0x0006, report_type:"input"},  // Generic Desktop / Keyboard, input reports
{usagePage:0x0001, usage:0x0006, report_type:"output"},  // Generic Desktop / Keyboard, output reports

It might make sense to do the same for Generic Desktop / Mouse and Generic Desktop / Keypad but I haven't come across any examples of devices that would benefit.

nondebug commented 1 year ago

Chromium has updated its blocking behavior (https://crrev.com/c/4450937) to effectively make this blocklist change.

These rules:

  {usagePage:0x0001, usage:0x0002},  // Generic Desktop / Mouse
  {usagePage:0x0001, usage:0x0006},  // Generic Desktop / Keyboard
  {usagePage:0x0001, usage:0x0007},  // Generic Desktop / Keypad

Will be replaced by:

  {usagePage:0x0001, usage:0x0002, report_type:"input"},  // Generic Desktop / Mouse, input reports
  {usagePage:0x0001, usage:0x0002, report_type:"output"},  // Generic Desktop / Mouse, output reports
  {usagePage:0x0001, usage:0x0006, report_type:"input"},  // Generic Desktop / Keyboard, input reports
  {usagePage:0x0001, usage:0x0006, report_type:"output"},  // Generic Desktop / Keyboard, output reports
  {usagePage:0x0001, usage:0x0007, report_type:"input"},  // Generic Desktop / Keypad, input reports
  {usagePage:0x0001, usage:0x0007, report_type:"output"},  // Generic Desktop / Keypad, output reports