WebUSB
View on WikipediaWebUSB is a JavaScript application programming interface (API) specification[1] for securely providing access to USB devices from web applications.[2]
It was published by the Web Platform Incubator Community Group. As of July 2021, it is in Draft Community status, and is supported[3] by Chromium-based browsers.
Introduction
[edit]A Universal Serial Bus, or a USB is an industry standard communication protocol used to communicate data across connectors, and cables from computers to peripheral devices and/or other computers.[4] WebUSB is a set of API calls that enable access to these hardware devices from web pages. WebUSB is developed by the World Wide Web Consortium (W3C).[1] The WebUSB API provides a safe, and developer familiar means of communication to edge devices from web pages. The WebUSB API integrates into existing USB libraries and shortens the development cycle for integrating new devices into the web environment by not needing to wait for browser support for these devices.
Early versions of WebUSB came out around as an alternative to Flash, Chrome Serial, and other custom approaches to connecting browsers to hardware. WebUSB aims to solve the four goals of any interface being; fast to make, cross platform, look good, accessibility.[5]
Application to Internet of Things (IoT) architecture
[edit]WebUSB API's are able to bridge hardware protocols to internet protocols, enabling the creating of uniform gateways linking edge devices to a centralised networks.[6]
The explosion in computing ability over the last few decades has led to an increase in edge devices. Devices such as lights, thermometers, HVAC, motors are increasingly integrated into centralised internet control servers.[7] These devices have evolved from isolated and previously non-integrated development environments. Consequently, they lack the uniform and consistent communication protocol necessary to develop an immediate connectivity to a web service. The WebUSB's API framework standardises disparate protocols and is able to expose non-standard Universal Serial Bus (USB) compatible devices to the web.[8]
The WebUSB looks to sit between the perception layer and the network layer.[6] The main goals of software in this gateway are; Scalability, Cost and reliability. The cloud-based deployment of WebUSB libraries enables it to cover scalability, its low overhead deployment significantly lowers cost, and its continual in use development over its lifetime has enabled the framework to attain a high degree of reliability.[9]
WebUSB has formed a cornerstone of the BIPES (Block based Integrated Platform for Embedded Systems) architecture framework. This systems architecture model aims to reduce complexity of IoT systems development by aggregating relevant software into 'Blocks' that are complete units of code and can be deployed to an edge device from a centralised cloud infrastructure.[10] As already mentioned the role of WebUSB is critically tied to its ability to communicate to embedded software through the USB communication protocol. Once the information is inside WebUSB's JavaScript environment it can be transposed and communicated through a variety of software protocols.[1] In this particular architecture model WebUSB bridges the gap between embedded software, and the web browser. The web browser then communicates to the cloud environment using uniform WebUSB constructed data.[10]
Security considerations
[edit]WebUSB provides a web page access to a connector to an edge device. The exposure of any device to the internet carries inherent risks and security concerns.[7] By product of design USB ports are designed to trust the device they are connected to. Connecting such a port to an internet facing application introduced a new set of security risks and massively expanding the attack surface for would be malicious actors.[8][1]
For instance a malicious host web page could request data from a peripheral device, which the device would happily fulfil thinking it was communicating through a standard USB connector. To mitigate this type of attack WebUSB developed a requestDevice() function call. This would notify the user that the site was requesting access to the edge device. This is similar to the access requests browser control for when a web page would like to access the inbuilt camera or microphone. Depending on the wariness of the user this protocol can be enough to prevent certain attacks. A second protocol that was developed is the specification of a request originating from a secure context.[11][1] This ensures that both the code to be executed and the data returned is not intercepted or modified in transit. This security is implemented through the claimInterface() function. This is an OS supported function, and ensures that only a single execution instance can have user space or kernel space driver access to the device, preventing malicious code on a web page from opening a second channel of communication to the device.[1] Other security considerations included created a public registry of approved connections, but this idea was ultimately scrapped as it required vendors to develop devices with WebUSB in mind.[1]
The threat surface of a USB however is bi-directional and a malicious peripheral device could attack the host. An infected edge device cannot easily be mitigated by WebUSB API's. In many device configurations trusted USB ports are used to deliver firmware upgrades and a malicious edge device could grant attackers persistence in a system.[11][4]
In light of the security concerns posed by WebUSB, it is only supported by an estimated 76% of browsers. Support for WebUSB at a browser level has been volatile over time, with certain browsers turning off access for periods of time after the discovery of particular security threats.[12] This fluctuation in support is similar to Adobe Flash and Google Serial, which failed to take off because they were unable to be used with adequate answers to fundamental security risks.[5]
Use in multi-factor authentication
[edit]The ability to own and verify a digital identity on the internet is critical to interaction with internet facing infrastructure. WebUSB in combination with special purpose devices and public identification registries can be used as key piece in an infrastructure scale solution to digital identity on the internet.[13] WebUSB API library is able to standardise the connection of peripheral devices to web pages. The security investment in WebUSB makes it a suitable software component in connecting identifiable devices to the internet.[1] Recent research has shown the fallibility of SMS based authentication highlighting how key pieces of the infrastructure can be subverted.[14] Alternative proposals for securing a digital identity involve the use of biometric sensors and/or personal identifiers. However, while these are good at identifying an individual, it is only through WebUSB that they can adequately be integrated into the existing internet tech stack.[13] Cryptographically secure solutions for personal identification exist with support from government and specialised hardware. However, these solutions lack generalised specification for web based infrastructure and are generally hard to support. Gateway support for such a communication protocol can be supported by software middlemen, such as WebUSB.[10][13]
A model system for multi-factor authentication uses WebUSB in tandem with an identifying hardware such as an ID card built to ISO/IEC 7810:2003 ID-1[15] standards. This card would constitute a physical representation of an individual's identity. WebUSB would then act as a middle man in facilitating the transfer of data stored on the hardware to a given web server. The number card would be digitally signed by an authorised party and would digitally connect to a server. This connection would require a device capable of reading ISO/IEC 14443 type B connections.[16] In order to make this digital connection valid, WebUSB would serve as software connector.[13]
Usage
[edit]WebUSB will only work on supported browsers, for example Chrome. Due to privacy and security concerns it will also only work in a secure context i.e.; over HTTPS, and can only be called through a user actions.
For instance in order to instantiate a connection navigator.usb.requestDevice() can only be called through user gesture, such as touch or mouse click.
Similarly protection from WebUSB can be provided using a feature policy. For instance Feature-Policy: fullscreen "*"; usb "none"; payment "self" https://payment.example.com would prevent WebUSB from running.[17]
To get access to devices visible to the browser two options are available. navigator.usb.requestDevice() will prompt the user to select which USB access is to be given, or navigator.usb.getDevices() will return a list of USB devices that the origin has access to.
To better search for devices, WebUSB has a number of filtering options. These filters are passed into navigator.usb.requestDevice() as a JavaScript filtering object. These filters are; vendorId,productId,classCode, protocolCode, serialNumber, and subclassCode.
For example, imagine connecting to an Arduino device, this could be done in the following way. Where 0x2341 is Arduino in the list of USB ID's[18]
navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
.then(device => {
console.log(device.productName);
console.log(device.manufacturerName);
})
.catch(error => { console.error(error); });
The USB device descriptor returned from the above snippet will contain all important information about the device such as; version, packet size, configuration options etc.
The alternative call to navigator.usb.getDevices() will instead look like this;
navigator.usb.getDevices().then(devices => {
devices.forEach(device => {
console.log(device.productName);
console.log(device.manufacturerName);
});
})
In order to talk to the device there are a few important function calls to run through. device.open() will run through all the required steps of setting up the device, device.selectConfiguration() sets up the configuration, importantly how it is powered, and the number of interfaces. It is then important to claim the interface. This can be done through the device.claimInterface function call. This will simulate a real wired connection and ensure that this web page is the only one able to read and write to the device until the connection is released. Finally the call device.controlTransferOut() will set up the device to communicate through the WebUSB Serial API. Once the set up is all done, data can be transferred to the device using device.transferIn() to transfer bulk data to the device, similarly its sister function device.transferOut() to read data from the device.[17][1]
Interfaces
[edit]In order to generalise interaction with hardware devices WebUSB supports a number of interfaces that abstract away the specific hardware functionality.[8]
| Interface Name | Description |
|---|---|
| USB | Provides attributes and methods for finding and connecting USB devices from a web page. This interface inherits from EventTarget.
|
| USBConnectionEvent | This connection event is passed to USB.onconnect or USB.ondisconnect when the agent detects a change in the connection status.
|
| USBDevice | Interface that provides metadata about the connected device and methods for controlling it. Importantly this is the main interface the developer will use for interacting with the device. |
| USBInTransferResult | A representation of the results from a data transfer event from the device to the host. Including field for the data and the status of the transfer. There are three options for status fields; 'ok' meaning the transfer was a success, 'stall' indicating an error producing a stall on the endpoint, or 'babble' which indicates more than expected data was transferred. |
| USBIsochronousInTransferResult | Similar to USBInTransferResult this is a representation of a data transfer from the device to the host when done across an isochronous endpoint. Has no status field, only the packets.
|
| USBIsochronousInTransferPacket | Represents the status of an individual packet from a request to transfer data from the device to the host over an isochronous endpoint. Can return the status of either 'ok' or 'stall'. |
| USBIsochronousOutTransferResult | Similar to USBInTransferResult this is a representation of a data transfer from the host to the device when done across an isochronous endpoint.
|
| USBIsochronousOutTransferPacket | Represents the status of an individual packet from a request to transfer data from the host to the device over an isochronous endpoint. Same status fields as USBIsochronousInTransferPacket.
|
| USBConfiguration | Provides information about a particular configuration of a USB device . This includes information about device version, maximum packet size and supported interfaces. |
| USBInterface | Provides information about an interface provided by the USB device. This includes information on whether it is claimed, as well as its communication protocol. |
| USBAlternateInterface | Provides information about a particular configuration of an interface and the particular modes the device can operate in. |
| USBEndPoint | The USBEndPoint is a unidirectional data stream either into or out of the device.
|
References
[edit]- ^ a b c d e f g h i Grant, R (2021-10-06). "WebUSB API". WICG. Retrieved 2022-01-07.
- ^ "Access USB Devices on the Web". Google Developers. 30 March 2016.
- ^ "WebUSB | Can I use... Support tables for HTML5, CSS3, etc". caniuse.com. Retrieved 2021-07-02.
- ^ a b Anderson, Don (2001). Universal Serial Bus System Architecture (2nd ed.). Addison-Wesley. ISBN 978-0-201-30975-1.
- ^ a b Hinton, Suz (2018-06-18). Suz Hinton - I'm afraid your browser has been talking to the robots again a gentle intro to WebUSB. CSSSConf Australia.
- ^ a b Beniwal, Gunjan; Singhrova, Anita (2022). "A systematic literature review on IoT gateways". Journal of King Saud University - Computer and Information Sciences. 34 (10): 9541–9563. doi:10.1016/j.jksuci.2021.11.007. S2CID 244758915.
- ^ a b Rondon, L; Babun, L; Aris, A; Akkaya, A; Uluagac, A (2021). "Survey on Enterprise Internet-of-Things systems (E-IoT): A security perspective". ISO. arXiv:2102.10695. Retrieved 2021-12-19.
- ^ a b c "WebUSB API". Mozilla Developer Blogs. Mozilla. 2021. Retrieved 2021-12-19.
- ^ Talukder, A.K (2020). "The Next Generation Web: Technologies and Services". Big Data Analytics. Lecture Notes in Computer Science. Vol. 12581. pp. 209–229. doi:10.1007/978-3-030-66665-1_14. ISBN 978-3-030-66664-4. S2CID 230795240. Retrieved 2021-12-19.
- ^ a b c Junior, A. G. D. S.; Gonçalves, L. M. G.; De Paula Caurin, G. A.; Tamanaka, G.T.B; Hernandes, A.C; Aroca, R.V (2020). "BIPES: Block Based Integrated Platform for Embedded Systems". IEEE Access. 8: 197955–197968. Bibcode:2020IEEEA...8s7955J. doi:10.1109/ACCESS.2020.3035083. S2CID 226854474.
- ^ a b Lindström, R (2021). "Enabling Smartphones to act as IoT Edge Devices via the Browser-based 'WebUSB API' : The future of the browser and the smartphone in home electronics IoT systems".
- ^ "Google disables WebUSB in Chrome amidst phishing concerns". XDA Developers. 7 March 2018.
- ^ a b c d Fujita, Y; Inomata, A; Kashiwazaki, H (2019). "Implementation and Evaluation of a Multi-Factor Web Authentication System with Individual Number Card and WebUSB". Asia-Pacific Network Operations and Management Symposium.
- ^ Brian Krebs (2018-06-01). "Reddit Breach Highlights Limits of SMS-Based Authentication". krebs on Security. Retrieved 2021-12-19.
- ^ "ISO/IEC 7810:2003 - Identification cards – Physical characteristics". Retrieved 2022-01-07.
- ^ "ISO/IEC 14443-1:2018 - Cards and security devices for personal identification – Contactless proximity objects". Retrieved 2022-01-07.
- ^ a b Beaufort, Francis (2021-02-23). "Access WebUSB". web.dev. Retrieved 2022-01-06.
- ^ "Access WebUSB". web.dev. Retrieved 2022-01-06.
External links
[edit]WebUSB
View on GrokipediaOverview
Definition and Purpose
WebUSB is a JavaScript API specification developed by the Web Platform Incubator Community Group (WICG) that provides secure access to Universal Serial Bus (USB) devices directly from web applications, eliminating the need for native plugins or drivers.[6] This API allows web pages to interact with a wide range of USB hardware, particularly those lacking standardized device classes defined by the USB Implementers Forum.[6] The primary purpose of WebUSB is to expose non-standard USB-compatible device services to the web platform, enabling developers to create applications that communicate with specialized hardware in a standardized, browser-native manner.[3] By bridging the gap between web technologies and USB peripherals, WebUSB facilitates safer and more accessible device interactions, reducing reliance on platform-specific software installations that can introduce security risks or compatibility issues.[6] Key benefits of WebUSB include its cross-platform compatibility, which empowers hardware manufacturers to distribute JavaScript SDKs that function uniformly across operating systems like Windows, macOS, Linux, Android, and ChromeOS without custom drivers.[3] It incorporates permission-based access, requiring explicit user consent through methods likenavigator.usb.requestDevice() to prevent unauthorized device interactions, and operates only in secure contexts to mitigate potential vulnerabilities.[6] Additionally, WebUSB supports integration with modern web ecosystems, including progressive web apps (PWAs).[3]
As part of the evolving web platform, WebUSB complements related APIs such as Web Bluetooth for low-energy wireless devices and Web Serial for serial port communications, collectively expanding browser capabilities for direct hardware integration without compromising user privacy or security.[7]
History and Development
The WebUSB API originated as a proposal in November 2015, introduced by Google engineer Reilly Grant within the Web Incubator Community Group (WICG), aimed at enabling web applications to access USB devices directly and securely, thereby expanding beyond the limitations of deprecated plugins such as NPAPI.[8] This initiative sought to empower hardware manufacturers to develop JavaScript-based SDKs for their devices, reducing reliance on platform-specific native code and fostering cross-platform innovation.[9] The initial proposal included a draft specification prototyped in Chrome for desktop platforms, complete with demonstrations for devices like Arduino boards.[8] Key milestones followed rapidly, with the first draft specification published in late 2015 and experimental integration into Chrome Canary builds beginning in early 2016, accessible via runtime flags.[10] The API progressed through iterative WICG drafts, with security considerations such as user-mediated device selection and origin-based permissions to mitigate risks of unauthorized access.[11] By September 2017, WebUSB achieved stable implementation in Chrome 61, marking its availability without experimental flags on supported platforms including Windows, macOS, Linux, ChromeOS, and Android.[12] Development has continued through the WICG GitHub repository, with ongoing refinements to the specification, including enhancements for improved error handling in device communication and refined filtering mechanisms using vendor and product IDs to better support selective device enumeration.[6] As of February 2025, WebUSB remains an incubating standard under WICG, without full W3C Recommendation status, reflecting its experimental yet maturing role in web platform evolution.[6] Primary contributions have come from Google engineers, with alignment to USB Implementers Forum (USB-IF) standards for device classes and descriptors to ensure compatibility with established USB protocols.[9][3]Technical Specifications
The WebUSB API is defined in an active WICG Editor's Draft as of February 2025.[2]Core API Interfaces
The WebUSB API is built upon a set of JavaScript interfaces that enable web applications to interact with USB devices securely and asynchronously. These core interfaces provide the foundational mechanisms for device discovery, configuration, data transfer, and event management, adhering to the USB protocol standards while integrating with the web platform's permission model.[2] The entry point to the WebUSB functionality is theNavigator.usb property, which exposes the USB interface on the Navigator object, available in both window and worker contexts. This interface includes the getDevices() method, which returns a Promise resolving to an array of USBDevice objects representing devices for which the origin has previously obtained permission. Additionally, requestDevice(options) prompts the user to select and grant permission to a USB device matching the provided filters, such as vendor ID or product ID, returning a Promise for the selected USBDevice. Event handlers onconnect and ondisconnect allow listening for device attachment and detachment events.[13][14][15][16]
The USBDevice interface represents an individual connected USB device and encapsulates its descriptors and operational methods. Key properties include vendorId and productId (unsigned shorts identifying the manufacturer and product), deviceClass, deviceSubclass, and deviceProtocol (octets describing the device's communication class), as well as version details like usbVersionMajor, usbVersionMinor, and usbVersionSubminor for the supported USB protocol. Optional string properties such as manufacturerName, productName, and serialNumber provide human-readable device information when available. The configurations property is a frozen array of USBConfiguration objects listing supported configurations, while opened is a boolean indicating if a session is active. Methods for device management include open(), which initiates a session returning a Promise<void>; close(), which ends the session; selectConfiguration(configurationValue), which applies a specific configuration by its octet value; claimInterface(interfaceNumber) and releaseInterface(interfaceNumber) for exclusive access to interfaces; and selectAlternateInterface(interfaceNumber, alternateSetting) to switch alternate settings within an interface. For data transfers, USBDevice supports control transfers via controlTransferIn(setup, length) and controlTransferOut(setup, data?), returning Promise<USBInTransferResult> or Promise<USBOutTransferResult> respectively; bulk and interrupt transfers through transferIn(endpointNumber, length) and transferOut(endpointNumber, data) returning Promise<USBInTransferResult> or Promise<USBOutTransferResult>; and isochronous transfers with isochronousTransferIn(endpointNumber, packetLengths) returning Promise<USBIsochronousInTransferResult> and isochronousTransferOut(endpointNumber, data, packetLengths) returning Promise<USBIsochronousOutTransferResult>. Other utilities include clearHalt(direction, endpointNumber) to resolve stalled endpoints, forget() to revoke permissions, and reset() to reinitialize the device.[17][18][19][20][21][22][23][24][25][26][27]
The USBInterface interface describes a specific interface within a device's configuration, used for claiming and managing functional units. Properties include interfaceNumber (an octet identifier), claimed (a boolean indicating exclusive access), alternate (the current USBAlternateInterface), and alternates (a frozen array of all available alternate interfaces for that number). Each alternate interface may define different endpoints or settings for varying operational modes.[28][29]
Complementing this, the USBEndpoint interface models the communication channels (endpoints) on an interface for data exchange. Properties encompass endpointNumber (octet), direction (an enum value from USBDirection as "in" or "out"), type (from USBEndpointType as "bulk", "interrupt", or "isochronous"), and packetSize (unsigned long for maximum packet capacity). Endpoints facilitate the four USB transfer types: control for setup and configuration; bulk for reliable, high-volume data without timing guarantees; interrupt for periodic, low-latency notifications; and isochronous for time-sensitive streaming with bandwidth reservation but no error correction.[30][31][32]
Results from control, bulk, and interrupt inbound transfers are handled by the USBInTransferResult interface, featuring a data property (nullable ArrayBufferView containing received bytes) and status (a string enum such as "ok", "stall", or "babble" indicating success or error conditions). For isochronous inbound transfers, USBIsochronousInTransferResult provides a packets array of individual packet results, each with status and data. For outbound transfers, USBOutTransferResult provides bytesWritten (unsigned long for the count of successfully transmitted bytes) and the same status property; isochronous outbound uses USBIsochronousOutTransferResult with packets array of {status, bytesWritten}. These structures ensure asynchronous handling of transfer outcomes in web applications.[33][34][35][36][37]
Event handling for USB dynamics is managed through the USBConnectionEvent interface, dispatched on the USB object via connect and disconnect events. Each event includes a device property referencing the affected USBDevice, allowing applications to respond to hot-plug scenarios without polling. This integrates seamlessly with the web's event-driven model for robust device management.[38][39]
Device Enumeration and Communication
Device enumeration in WebUSB begins with thenavigator.usb.getDevices() method, which asynchronously returns a list of USBDevice objects representing USB devices that the user has previously authorized the origin to access, ensuring persistent connections without repeated prompts.[40] For discovering new devices, the navigator.usb.requestDevice() method prompts the user to select from available USB devices, optionally filtered by criteria such as vendorId (a 16-bit identifier for the device manufacturer), productId (a 16-bit product identifier requiring a matching vendorId), or classCode (an 8-bit USB class code for device categories like vendor-specific or human interface devices).[41] These filters allow web applications to target specific hardware, such as a device with vendorId: 0x1209 and productId: 0x0d28 for a microcontroller, narrowing the selection to relevant options and improving user experience.[42]
The connection workflow establishes a communication session with the selected USBDevice. It starts with calling device.open(), which initiates the session and verifies the device's availability, followed by device.selectConfiguration(configurationValue) to activate a specific configuration from the device's USB descriptors, typically the first one (value 1) for simple devices.[43] Interfaces are then claimed using device.claimInterface(interfaceNumber) to exclusively access endpoints for data transfer, such as interface 0 for a basic serial port emulation.[23] Resources are released via device.releaseInterface(interfaceNumber) when no longer needed, and the session ends with device.close() to free system resources and handle disconnection gracefully.[44] WebUSB supports compatibility across USB versions through the usbVersionMajor, usbVersionMinor, and usbVersionSubminor properties of the USBDevice, accommodating USB 2.0 (version 2.0.0) for low-speed/full-speed devices and USB 3.0/3.1 (versions 3.0.0 and higher) for high-speed/super-speed transfers, though browser implementations may limit support to USB 2.0 in practice for stability.[20]
Data communication in WebUSB relies on transfer methods tailored to USB protocols, all operating on byte-level data via ArrayBuffer or Uint8Array for efficient handling of binary payloads. Control transfers, used for setup requests like querying descriptors or sending commands, employ device.controlTransferIn(setup, length) to receive data and device.controlTransferOut(setup, data) to send it, where the setup parameter defines the request type, recipient, and parameters per USB standards.[24] Bulk transfers for reliable, non-time-critical data streams, such as file uploads to a USB drive, use device.transferIn(endpointNumber, length) and device.transferOut(endpointNumber, data), targeting bulk endpoints identified by number and direction.[25] Isochronous transfers, suitable for real-time streams like audio or video, are handled by device.isochronousTransferIn(endpointNumber, packetLengths) and device.isochronousTransferOut(endpointNumber, data, packetLengths), allowing specification of packet sizes to match bandwidth requirements without retransmission guarantees.[26]
Error management is integral to robust WebUSB applications, with the API throwing standardized DOM exceptions to indicate failures. A NotFoundError occurs if the requested device, interface, or endpoint is unavailable, such as when a filtered requestDevice() yields no matches or a device disconnects mid-session, resolvable by re-enumerating devices or monitoring connect/disconnect events.[45] NotAllowedError signals permission denial, often from user rejection during requestDevice(), which can be mitigated by providing clear prompts and handling the promise rejection to avoid crashes.[41] InvalidStateError arises from operations on unopened devices or unclaimed interfaces, like attempting a transfer before open() or claimInterface(), typically resolved by verifying the device state with properties like opened and sequencing calls correctly.[25] Applications should wrap API calls in try-catch blocks to capture these exceptions and implement fallbacks, such as retrying after a brief delay for transient issues.
WebUSB provides programmatic access to USB descriptors, enabling applications to inspect device capabilities without manual parsing. The USBConfiguration interface exposes details like configurationValue, configurationName, and interfaces array, retrieved after selectConfiguration().[46] USBInterface objects provide interfaceNumber and access to alternate interfaces via alternate and alternates; the USBAlternateInterface objects detail alternateSetting, interfaceClass, interfaceSubclass, interfaceProtocol, and endpoints array, allowing selection of the appropriate alternate for features like high-bandwidth modes.[28][47] Endpoints are represented by USBEndpoint with properties including endpointNumber, direction (in or out), type (bulk, interrupt, isochronous), and packetSize, facilitating endpoint selection for transfers based on the device's declared bandwidth and latency needs.[30] These descriptors conform to USB 2.0 and 3.x standards, parsed automatically by the browser to abstract low-level details while ensuring compatibility.[48]
Applications
Internet of Things Integration
WebUSB facilitates the creation of web-based dashboards for Internet of Things (IoT) applications by enabling direct browser access to USB-connected sensors, actuators, and controllers, such as Arduino boards or ESP32 microcontrollers, without requiring dedicated desktop software or native drivers. This integration allows developers to build interactive interfaces where users can monitor environmental data from sensors or control actuators like motors and LEDs directly through JavaScript, streamlining IoT prototyping and deployment in educational or hobbyist settings. For instance, libraries like the WebUSB Arduino library enable sketches to expose device capabilities to web pages, permitting real-time interaction via Chrome's USB chooser prompt.[49][50] The architecture of WebUSB offers significant benefits for IoT ecosystems by eliminating the need for custom operating system drivers, as the API handles USB communication natively within the browser, promoting cross-platform compatibility across Windows, macOS, Linux, Chrome OS, and Android devices. It supports remote firmware updates by allowing web applications to transfer encrypted update payloads to devices, as demonstrated in prototypes using the WebUSB API to simulate secure over-the-air-like updates on microcontrollers. Additionally, real-time data streaming is achieved through bidirectional transfer methods liketransferIn and transferOut, enabling continuous sensor data flows for applications such as live monitoring in smart home setups, with packet handling optimized for low-latency IoT interactions.[2][1][51]
In practice, WebUSB integrates with IoT platforms like Node-RED to create USB-connected gateways for device orchestration, where flows can process data from Johnny-Five-compatible hardware, allowing browser-based control of multiple sensors and actuators in automated workflows. For example, projects combine WebUSB with Node-RED to enable Android-hosted IoT bots that respond to web commands, facilitating low-power control in smart home ecosystems like lighting or environmental regulation without intermediary servers. While direct Home Assistant integrations via WebUSB remain emerging, USB gateways in such platforms can leverage WebUSB for browser-extended device management in local networks.[52]
WebUSB's scalability for IoT is enhanced by its device enumeration mechanisms, which use filters based on vendor ID, product ID, and serial number to selectively connect to specific devices among multiple attached ones, avoiding permission prompts for each. The getDevices() method retrieves an array of previously authorized USBDevice objects, supporting concurrent management of several IoT peripherals, such as in distributed sensor arrays.[53][54][55]
Multi-Factor Authentication
WebUSB enables web applications to communicate directly with hardware cryptocurrency wallets, such as Trezor, for secure transaction signing and device verification, providing a form of multi-factor authentication in blockchain and financial applications. These devices use public-key cryptography to sign transactions without exposing private keys, ensuring phishing resistance.[56] In the workflow, a web application requests user permission to access the device via the WebUSB API. The browser prompts for consent, then facilitates communication through control, bulk, and interrupt transfers to send signing challenges to the device, which processes them securely and returns the signed response bound to the application's origin.[3] This direct access eliminates the need for native drivers or plugins, enhancing cross-platform usability.[1] Compared to software-based methods, WebUSB with hardware wallets offers improved security by keeping private keys isolated on the device. It supports integration with web-based wallet interfaces for passwordless or multi-step verification processes. Adoption has grown in cryptocurrency ecosystems, with Trezor Suite web app leveraging WebUSB since around 2020 for seamless device interaction.[57] Password managers and exchanges also incorporate similar hardware for secure key management.Scientific and Industrial Devices
WebUSB facilitates direct access to laboratory equipment such as oscilloscopes, spectrometers, and data loggers through the USB Test and Measurement Class (USBTMC) protocol, allowing web applications to control these devices without requiring native drivers or additional software installations.[58] This integration enables browser-based tools to send commands, retrieve measurements, and perform real-time analysis, such as querying instrument identities or capturing waveforms from oscilloscopes.[58] For instance, the WebUSBTMC library implements USBTMC over WebUSB, supporting operations like frequency response analysis that plot Bode and Nyquist diagrams using connected oscilloscopes.[58] In industrial settings, WebUSB supports integration with USB-connected programmable logic controllers (PLCs) and robotics systems for web-monitored automation and high-speed data acquisition. Projects like the Flea-Scope demonstrate this capability by providing a web interface for controlling a USB oscilloscope and logic analyzer at up to 18 MSPS, enabling real-time data capture and processing in manufacturing environments without proprietary applications.[59] Similarly, open-source firmware for Raspberry Pi Pico devices uses WebUSB to interface with peripherals for tasks like analog signal sampling at 500 kS/s, applicable to industrial monitoring of sensors or actuators.[60] The primary benefits of WebUSB in these professional contexts include the development of collaborative web platforms for remote experimentation, where multiple users can access and control shared instrumentation via browsers, and a reduction in dependencies on vendor-specific software in research labs.[3] This approach promotes open-source ecosystems, as seen in projects configuring Raspberry Pi Pico as USBTMC devices for scientific timing applications like pulse generators, fostering interoperability across diverse hardware setups.[61]Security and Privacy
Key Security Features
WebUSB incorporates several built-in security mechanisms to safeguard users and connected devices from unauthorized access and potential misuse. Central to its design is a robust user consent model, where therequestDevice() method mandates an explicit permission prompt from the user before granting access to any USB device.[2] This prompt allows users to select specific devices and choose between one-time access or persistent permissions, which are stored securely and can be revoked at any time through browser settings or by calling device.forget() in supported implementations.[3][1]
Access is strictly isolated to the requesting site's origin, leveraging the Permissions Policy to prevent cross-origin interference and mitigate risks such as cross-site scripting attacks that could target connected devices.[62] This origin-bound restriction ensures that only the authenticated web page can interact with the device, aligning with broader web platform security principles that require secure contexts (HTTPS) for all operations.[63]
To further limit exposure, WebUSB employs device filtering through the USBDeviceFilter interface in requestDevice() options, enabling developers to specify allowed vendor IDs, product IDs, or even serial numbers, thereby narrowing the scope to intended hardware.[2] By default, the API does not provide automatic access to standard USB classes like mass storage or Human Interface Devices (HID), and a built-in blocklist restricts interactions with known high-risk devices, such as those that could expose sensitive system data.[64] All communications occur within the browser's sandboxed environment, confining operations to JavaScript execution without granting direct operating system-level privileges, thus containing potential breaches to the web context.[1]
The API's security features comply with USB Implementers Forum (USB-IF) guidelines for device identification and communication protocols, as outlined in USB 3.1 specifications, and adhere to W3C privacy and security principles, including those in the Permissions API and Powerful Features documents, with updates as of early 2025 incorporating enhanced policy controls for isolated web applications.[65][66]
Potential Risks and Mitigations
One primary risk associated with WebUSB is that malicious websites can request access to sensitive USB devices, such as keyboards, storage drives, or authentication hardware, potentially leading to data exfiltration or unauthorized control if users grant permission through the browser prompt.[67] In a 2017 demonstration by WithSecure Labs, researchers used WebUSB in Chrome to access an Android phone via the Android Debug Bridge (ADB), exfiltrating files from the camera folder after the user enabled USB debugging and approved the connection, highlighting the danger of data theft from unlocked mobile devices connected via USB.[68] Similarly, in 2018, security researchers exploited WebUSB in Chrome to phish YubiKey Neo users by tricking them into granting access, allowing queries to the device's CCID interface and bypassing multi-factor authentication (MFA) protections despite requiring a physical key tap.[69] Additional concerns include the API's lack of built-in support for standard USB classes like Human Interface Device (HID), which reduces compatibility but shifts risks toward custom or proprietary devices that may not implement robust safeguards, potentially exposing users to unforeseen vulnerabilities.[70] WebUSB's permission model, while origin-bound, interacts with cross-origin resource sharing (CORS) principles by restricting access to granted origins, but improper implementation could still enable indirect data leakage if devices are shared across sessions.[71] A noted vulnerability in this area is CVE-2020-16033, where flawed WebUSB implementation in Chrome prior to version 87 allowed remote attackers to spoof security user interfaces through crafted HTML pages.[72] To mitigate these risks, developers are advised to request only necessary permissions via therequestDevice() method and to design applications that minimize data exposure, aligning with the API's requirement for secure contexts (HTTPS) to prevent network-based injection attacks.[67] User education emphasizes scrutinizing permission prompts—such as those for device selection and interface claiming—before granting access, as WebUSB relies heavily on explicit user consent to block unauthorized interactions.[11] Browser extensions, like those developed to disable WebUSB entirely, provide an additional layer of protection for users concerned about phishing or unintended access.[73] The specification incorporates a device blocklist to restrict access to known problematic hardware based on vendor and product IDs, which is periodically updated, and integrates with the Permissions Policy to allow site administrators to limit USB feature usage via HTTP headers.[74] In response to identified issues, such as the YubiKey vulnerability, Google collaborated with Yubico to implement fixes in Chrome updates, including disabling WebUSB for affected devices until broader resolutions were available.[75]
WebUSB's consent mechanisms, including origin-specific permissions stored via the Permission API, help align with privacy regulations like the EU's General Data Protection Regulation (GDPR) by ensuring explicit user control over personal data processing through connected devices.[62] Security researchers have conducted audits highlighting these risks, with demonstrations and CVEs up to 2020 informing ongoing improvements, though no major specification overhauls were reported by 2025.[76]
Implementation and Support
Browser Compatibility
WebUSB enjoys robust support in Chromium-based desktop browsers. Google Chrome has provided full implementation since version 61, released in September 2017, enabling developers to access USB devices directly from web applications in secure contexts. Microsoft Edge followed with complete support starting from version 79 in January 2020, aligning with its transition to the Chromium engine. Opera, also built on Chromium, has offered full compatibility since version 48 in September 2017. In the latest releases, such as Chrome 142 and Edge 142 as of November 2025, all specification features are available without the need for experimental flags, though usage remains restricted to HTTPS environments to mitigate security risks.[1][77] Mozilla Firefox lacks native support for WebUSB, with no implementation available up to version 145 as of November 2025. This decision stems from ongoing security and privacy concerns articulated by Mozilla since at least 2018, positioning the API as incompatible with their standards for web safety. Apple Safari and other WebKit-based browsers similarly offer no native support as of 2025, up to Safari 26.1. Although WebKit has explored limited exposure of WebUSB to browser extensions as a migration path since 2022, this has not progressed to stable releases due to heightened risks of device access in an open web environment.[70][1][78][77] On mobile platforms, WebUSB compatibility mirrors desktop limitations in Chromium derivatives. Chrome for Android has supported the API fully since version 61, allowing USB interactions on compatible devices. However, Safari on iOS provides no support up to version 26.1, reflecting Apple's stringent controls on hardware access. Firefox for Android also remains unsupported up to version 145. Other mobile browsers, including Opera Mobile from version 80 and Samsung Internet from version 8.2, inherit Chromium's full support, though practical adoption is constrained by device permissions and OS-level USB handling.[1][77]| Browser | Desktop Support | Mobile Support | Notes |
|---|---|---|---|
| Chrome | Full (v61+) | Full (Android v61+) | Requires secure context; partial in workers.[1] |
| Edge | Full (v79+) | Full (Android via Chromium) | Aligned with Chrome implementation.[77] |
| Firefox | None (up to v145) | None (Android up to v145) | Security concerns prevent adoption.[70] |
| Safari | None (up to v26.1; experimental in TP) | None (iOS up to v26.1) | Experimental in WebKit extensions only.[78] |
| Opera | Full (v48+) | Full (Mobile v80+) | Chromium-based; consistent with Chrome.[77] |
Usage Guidelines and Examples
Developers implementing WebUSB should first perform feature detection to ensure the API is available in the user's browser environment. This involves checking the existence of thenavigator.usb property, as the API is only supported in secure contexts (HTTPS) and requires explicit user permission for device access.[1] If unsupported, applications must gracefully degrade, such as displaying a message prompting users to switch to a compatible browser like Chrome or Edge.[3]
The basic implementation follows a sequence of asynchronous steps: requesting the device, opening the connection, performing a transfer, and cleaning up resources. To request a device, call navigator.usb.requestDevice() with filters specifying criteria like vendor ID to prompt the user for selection; this returns a USBDevice object upon success. Next, invoke device.open() to establish the connection, which may involve claiming interfaces if needed. For a simple transfer, such as reading device information, use device.transferIn(endpointNumber, length) to receive data from the device, specifying the endpoint and buffer size (e.g., 64 bytes). Finally, call device.close() to release the device, preventing resource leaks.[2]
A representative asynchronous JavaScript snippet for connecting to a vendor-specific device (e.g., vendor ID 0x2341 for an Arduino-like device) and transferring 64 bytes of data is as follows:
if ('usb' in navigator) {
navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
.then(device => {
console.log('Device selected:', device.productName);
return device.open();
})
.then(() => device.transferIn(1, 64)) // Endpoint 1, 64-byte buffer
.then(result => {
const decoder = new TextDecoder();
console.log('Received [data](/page/Data):', decoder.decode(result.[data](/page/Data)));
})
.catch(error => {
console.error('Error during transfer:', error);
});
} else {
console.warn('WebUSB not supported');
}
This example assumes a bulk IN endpoint at index 1; actual endpoint indices depend on the device's configuration.[3]
Key guidelines for robust implementation include wrapping operations in try-catch blocks or using Promise .catch() handlers to manage errors like NotFoundError (device unavailable) or NetworkError (transfer failure), ensuring the application remains stable. To optimize performance, minimize the frequency of data transfers by batching requests where possible and avoid large payloads that could stall endpoints; for instance, limit transfers to under 64KB per operation in high-throughput scenarios. Always test implementations across supported browsers—primarily Chrome 61+, Edge 79+, and Opera 48+—to verify consistent behavior, as API nuances may vary slightly.[81][3]
For debugging, employ console logging to capture USB events, device properties, and transfer results, which helps trace issues like permission denials or stalled endpoints. Additionally, utilize browser-specific tools such as Chrome DevTools' Network panel to inspect USB transfers or the chrome://usb-internals page for detailed device logs and simulation capabilities.[1][3]