WebUSB is dead
hbyconsultancy.com
hbyconsultancy.com
I wish we separated the browser application from the VM application. ie, let us make simple, secure content with HTML and minimal CSS. For things like Wikipedia and even a lot of YouTube that's all you need. People can use an extremely simple (and private/secure!) program to access this kind of content. A text version of my personal site is browsable with cURL or even netcat[0].
Make the VM a separate program that people use for fancy web apps.
Browsers aren't stopping you or Wikipedia or Youtube from sticking to HTML and minimal CSS.
Your problem isn't with browsers, it's with Web developers who don't share your priorities.
You're right there's a chicken/egg problem: no-one's going to use that fantasy browser, because it can't browse the Web. We know this because faster experimental browsers exist, and essentially no-one uses them. Even browsers with tens or hundreds of millions of users struggle to get Web developer attention, even when they're almost completely compatible with the dominant browser and don't require fundamentally rearchitecting, and arguably crippling, one's Web site.
Also, from a technical point of view, ripping out JS and DOM APIs does not magically mean you get a "wicked-fast, private, secure browser". It would be a lot more secure, but building a fast HTML/CSS rendering engine that still has to handle window resizing, zooming, incremental loading, editing and other interaction is still incredibly hard, in fact not hugely easier than supporting JS. (Source: I'm a former Mozilla distinguished engineer who worked on this stuff.) By far the easiest path to such a browser would be to take an existing engine and rip out stuff, and I don't think you're going to end up with something much faster. Disabling JS in a regular browser is going to give you most of the wins.
True, general web layout is a hard problem. But there are a lot of knobs to turn. What if we removed CSS layout altogether, and only allowed linear pages, a la reader mode? That's a big tradeoff, but maybe it would work. If that's too much, maybe only allowing flexbox would be enough. As for editing, at that point you're making a web app.
Are you getting rid of Web forms now? Also, remember that at the very beginning Berners-Lee's WorldWideWeb browser supported HTML editing, so it's definitely part of some vision of the "good old days".
Yes, if you cut down or eliminate CSS, or just redesign it, you could build a faster renderer.
But these questions point to one of major defects of the "cut-down Web" vision: lots of people have a limited set of Web features that they like, but they tend not to agree on what that set is. You like flexbox. Some people really like grid. Some people really need ruby, or floats, or columns, or editing, or vertical breaking (pagination). Pretty soon you've got something nearly as complicated as real CSS.
Democracy to the rescue:
1. Start a FLOSS mailing list thread to get as much input as possible on the best starting point for this reduced set of functionality. Gopher, resurrecting Xanadu, revisiting Hypercard, and so on. Let the conversation flow.
2. Invite the people who chose Firefox Reader View to private gitlab instance and get to work.
The browser you describe already exists, it's one with JS disabled, and you ignore the sites which don't work without it. This is how I browse every day.
I don't feel like I'm missing much.
I enable JS for reddit because I have to mod things, but I find myself visiting that site less and less now. HN works. Facebook works (good enough.) Gmail works. Google Search and DDG work. GitHub... meh.
I seriously hope this will never happen.
But the demand isn't that big, and the effort wouldn't have much return.
This is sort of like saying: Just because the computer doesn't have a password doesn't stop you from simply not using computers you're not supposed to. So your problem is not with the lack of passwords but with people who use computers they aren't supposed to.
You can get most of the security benefits by disabling JS in the browser.
Moving the software into the browser improved latency, but questions like "Is this webpage doing something dangerous/annoying?" became undecidable. If we provably cannot determine if a webpage will halt without running it, we obviously cannot as any more complicated questions about the webpage's behavior. As long as webpages have access to a Turing complete language, the browser will be de facto an OS. Unfortunately, returning to a web of documents isn't going to happen anytime soon; too many people profit from this ability to run programs on other people's computers.
(Gary Bernhardt's amazing (and terrifying) talk "The Birth & Death of JavaScript"[1] was absurdist comedy, not a guide to future browser designs)
[1] https://www.destroyallsoftware.com/talks/the-birth-and-death...
Yes, I've resigned myself to this truth long ago. Since then, I've been watching the web get smaller and smaller as more and more websites break unless they're allowed to run code client side.
I fully expect that the majority of the web will become inaccessible to me within my lifetime. Alas, the future does not always bring wonderful things!
I mean, behaviour of a website may be undecideable. Behaviour over the 5 minutes you're viewing it is. I dont think notions from computability theory are particularly enlightening here.
Eg. Node.js doesn't have WebUSB either :)
Well, I don't think that's how it should be, but that's certainly how it's turning out.
How it should be is that websites degrade gracefully, and remain usable (if more limited in terms of geewhizzery) without client-side scripting.
No, the ship has sailed. Just activate JavaScript and block ads/trackers.
It absolutely has. That's a fundamental design goal for HTML.
> For example a simple auto complete field that loads things from the database as you type. There is no way "graceful" way to implement this without JavaScript.
True, so if the user doesn't have JS enabled, you don't do that. Omitting that functionality doesn't remove the ability to make use of the website.
You're arguing that making proper websites is too expensive to justify. That's your call, of course, but that's a different argument than "it can't be done".
> Just activate JavaScript and block ads/trackers.
No, that's too risky. What I'll do instead is not use the website.
A simple browser that only implemented a subset of HTML and the good parts of CSS (ie flexbox) could be implemented easily by a small team.
Most things that look like conspiracies are in fact unplanned outcomes that result from an unintentional alignment of multiple perverse incentives. A different way of saying the same is that most things that appear to be conspiracies are actually "emergent" behaviors in complex systems.
A different example of something similar is real estate hyperinflation. I don't think somebody sat down and said "lets make housing impossible for any family making less than 5X the local median income to reasonably afford." What happened instead was that multiple decisions made for independent and unrelated reasons created an aligned set of perverse incentives that drove the price of housing nuts. There is no one cause or one responsible party.
And thats ok in my opinion. The IETF describes itself as "rough consensus and running code" and it seems to work well. I dont have a problem with the web following that model.
EDIT: But that can also be explained by incentives+emergent behavior. So at the end of the day, you're simply correct.
The difference is they have much more aggressive automatic upgrade processes than Flash or Java did, so bugs remain usable for way less time. And Chrome did sandboxing.
But Firefox doesn't/didn't. It got a free pass from the community because Mozilla is somehow seen as "not a corporation" and did a lot of drum beating about openess/webbyness/etc. So people gave it a break although the architecture wasn't really any different to something like Java applets and if anything was much worse.
Example: Table sorting. Hell, maybe table pagination, too.
This is part of why developing HTML-based UI still seems so weird and shitty compared to native, even with the aid of Javascript. Those native SDKs provide way more support for common, basic use cases. Even within the narrow scope of rich document format & display, HTML without Javascript is crippled (see again: super-basic and common table functionality). Plus you'll get a hell of a lot better performance letting C/C++/Rust handle those kinds of basics, rather than trying to re-create them in CSS and Javascript.
Another example: there's a clear, fairly common need for tiled dynamically-loading images, as in maps applications. That should be a tag, and... that's all. Just a tag. To get that whole thing. A couple properties to enable/disable things like zooming. Some sensible standard for how to request tiles by X/Y at a given total canvas size (so, just a convention for image URLs) so that just has to be implemented once per server-side language, and can easily be pre-generated and served from actual files. A way to drop other elements on the image at some X/Y value for pins or linking people's faces to wikipedia entries or whatever, kinda like old school imagemap elements. That's clearly useful even for document-centric usecases (aside from maps, consider, say, ultra-high-res images of painted church ceilings). The browser and HTML should include that.
Search. Complete- or hint-as-you-type search fields should be a built-in element, with results from local or remote (some convention for the URL) markup-based sources.
There's a ton of stuff like that which, in 2020, really ought not require Javascript. Lots of which are still basically rich-document UI elements that've been in demand for 15-25 years at this point, with the holes filled a thousand times over at great cost in person-hours by slow, janky, battery-eating JS and CSS. And that's not even considering overhauling HTML to better suit use in "applications", which could also be done and arguably should be done, since we've pretty much lost the battle to keep that from happening.
I'd love more of the Web to be Javascript-light or -free, but modern HTML standards & clients aren't really up to the task. Mostly because (I think) Javascript has freed them from having to worry about it. "Table sorting by column? Well yes of course everyone wants that basically everywhere all the time, but let Javascript handle it".
You say that, and then you disprove your point by going on to list a bunch of extra features that that tag would have to have. And even with those features, major map sites wouldn't use it because they render map content client-side using vectors, not map tile images, and have lots of other features your tag wouldn't support.
Implementing your vision would mean a massive increase in the API surface of browsers, with concomitant increase in browser bloat, and browser and standards development effort ... while there's a strong argument that browsers are already too complicated.
Even so, when we've tried to implement declarative features on the Web we've seen over and over again that it's impossible to satisfy everyone's needs without scripting. (See e.g. HTML5 form validation, SVG vs canvas, VRML vs WebGL, ...) That is why stuff like the Extensible Web Manifesto emerged.
Feature interaction complexity between CSS features is a huge problem. Some of that could have been avoided if CSS had been designed differently, but some of it seems unavoidable (e.g. laying out text with mixed directions, mixed writing modes, ruby, font substitution, modern font features, etc etc --- at speed --- is just really complex).
Modern high-performance JS is really complicated to implement.
The plethora of APIs exposed to JS --- WebXYZ --- is incredibly complicated.
HTML is pretty complicated, e.g. HTML forms.
But if you take away JS, CSS/HTML don't get a whole lot easier, assuming you're still supporting interaction in some way. I mean, for your proposed map API, if the user can manipulate the functionality and you have lots of features that can be customized declaratively, it's not much more complicated to expose those controls to JS.
If you can simplify the problem so that CSS and HTML don't need to support incremental relayout/DOM changes, that would help a lot, but removing JS isn't enough for that. Things like zooming, window resizing, incremental loading, and any kind of editing put a lot of the same requirements on the engine.
Safari is still relevant due to iOS and iPad not macOS, and although I mostly use FF privatly, it is seldom a project acceptance requirement to also validate against it.
Ironically it were the IE haters that kind of helped this to happen.
From my point of view as a user: on one hand it kind of sucks because I use Firefox as my main browser, and launching Chrome/Chromium every time is a bit out of my usual path.
On the other hand, I appreciate not having to install something on my computer just for this. It's nice for small apps that you won't be interacting with that often or for too long.
You could imagine the same for an unzipping app. It theory, an unzipping app doesn't need anything else than specific file system permissions, i.e. read for a specific set of bytes and write access to a specific filepath.
https://github.com/GoogleChromeLabs/unarchiver
I work on the Capabilities team on Chrome and I think it's pretty cool the web can do more, and provide safe experiences for users.
I don't know whether WebUSB is healthy or not -- but the OP clearly doesn't either.
I interpret the definition of "dead" here to be:
No other implementation than the one in Chrome
Rather than: No implementation or spec work at allNow that might change as we soon will only have one browser.
I've been successful using these npm modules: "@nodert-win10-rs3/windows.devices.custom" and "enumerated" on Windows and "usb" on Mac. Interestingly, "usb" relies on libusb which isn't really an option for the common Windows user.
A naive developer will read about WebUSB and think, "oh, Electron is Chrome, so this must be a good solution!" but remember that Electron apps consist of one node process (main) and multiple chrome processes (renderers, aka, BrowserWindow objects).
In my experience, it is poor design to exclusively connect to USB hardware using a BrowserWindow. Instead, it's much better to use the main node process to handle all exclusive USB access, and then push state to renderers using IPC.
So, once you go down this road you realize that WebUSB on Electron isn't viable. The idea seems good, but was dead on arrival for me. Your mileage may vary.
Ten years ago I would never have identified as a hardware-focused software developer. Now it's become part of my professional identity. My speciality is Electron/USB. You can check out my USB-heavy Windows/Mac app at https://www.label.live. I'm available for consulting if you have a need for custom desktop software that talks to hardware. I've solved dozens of incredibly difficult problems over the last few years. Super fun.
You should absolutely not do this - don't do anything in the main process at all; blocking it even a little bit makes your entire app janky and hang'y. If you want to connect to USB hardware in an isolated context, create a hidden renderer process (aka a BrowserWindow that you don't call `show` on), though tbh I would just use your existing BrowserWindow, I'm not sure why you immediately dismiss it as "poor design".
And WebUSB is by no mean dead. Geez, it just got supported by Microsoft in the last version of Edge!
https://caniuse.com/#search=Web%20Bluetooth
I know you can connect game controllers to your computer, but maybe that uses the Gamepad API instead. Haven't dug too much into that but was playing with a Babylon Demo and thought the camera controls with a Xbox One Controller was a bit nicer than using my mouse.
I've played with WebBluetooth some and hope it gets more love!
Say they have their Magic Mouse, Magic Keyboard, Airpods(probably counts as 2 connections) and then sometimes the case status shows up too. So 5 connections. Looks like the limit is 7, so some are pushing it.
[0] https://superuser.com/questions/931188/how-many-devices-can-...
The website's comment system is what is dead. Getting a 403 when posting a comment: https://files.littlebird.com.au/Shared-Image-2020-02-04-20-1...
There is a lot of configuration management. An operator has to use the correct build of software, and needs to configure the software with the appropriate settings. After some testing he needs to save off the data to the appropriate places for analysis and archival.
It seems to me that this type of application would be appropriate to implement as a web application. This would help me manage deployments better and would automate the CM/data flows.
I have been casually monitoring the Web Serial, Web USB, and Web Socket APIs, since they would enable me to implement the low-level communications I need. The opposition to these standards bums me out, but I keep hoping that the security concerns can be resolved and that attitudes will change.
The last week's released Android Flash Tool, makes use of it.
It was a nasty, nasty hack, and things like this shouldn't be allowed. Management insisted that our product have a web-interface because they had information that our competitor was going from desktop apps to web apps. Ironically, our competitor was never able to get its web interface working.
WebUSB was really a very cool approach to connect Web to USB devices in spite of all the security issues that you may or you may not face. I had the chance to work on it and see its limitations two years ago. I found out very small of successful implementations and solutions (Google use it to flash Android from the web, finally (: ).
To make this thread more interactive, I am adding a proof of concept of a code generator to generate WebUSB code :-) https://github.com/hatemben/usbmon
Feel free to fork/test and play with. It's true that there are tons of security issues related to WebUSB, and there are always solutions to security issues. For me WebUSB is dead two years ago, I just remembered to announce it last week.
-Hatem
WebGPU is more useful but direct access to hardware that could have coherent memory access/DMA is just irresponsible.
Chrome needs it for chromebooks. Not sure why it's needed for less constrained machines.
If we spam users with requests like that and lose control of simple things, there's no chance for us to ask a meaningful question about webusb. I've seen this on my mom's mobile phone. It's full of news notifications that annoy her - because she defaulted to clicking "allow", because she's a typical user.
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)
Game over?
The upcoming WebHID API considers and mitigates this attack as well https://wicg.github.io/webhid/#introduction
(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?"
"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...)
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
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 :).
Have you reported the issue to the maker?
Has the responsible disclosure window elapsed?
Than will pick up on "this website wants to use your keyboard"
Your tech illiterate users fall for the former, but many people with just average technical knowledge would fall for the latter.
"This website uses your keyboard directly to secure your password, press yes when presented with the dialog"
I'm nervous about justifying one thing based on the fact that a different, objectively terrible, thing is allowed already.
Maybe give feedback here? https://github.com/WICG/webusb/issues/
"We identified the biggest security problem with this, but to get adoption we're going to rely on prompts (which we all know users pay attention to)"
Then the next section is:
"We know how the previous shortcomings can be exploited to pwn the host too, hosts, don't let yourselves get pwn'd k thnx"
What feedback is there to give, they know what's wrong, they just don't care.
If they have a way of truly sandboxing malicious uses, without entering into permissions request overload (no human is infallible), I'd love to hear it.
the "discussed at X f2f" is not filling me with confidence.
"Greetings, Rando Middle Manager. Your cousin Larry has been arrested by police in Elbonia. Please to pay US$500,000 into this Bitcoin account to free hime. Or if you do not have funds, plug in company secure USB drive and click OK."
A probably-viable (but also inconvenient) alternative is to code your own bridge: a server that talks the relevant USB protocol in the host OS and exposes an HTTP endpoint that a browser can connect to. More complicated than having the browser just be the bridge, and it introduces the significant risk of mis-implementing the security model and leaving your hardware open for remote-zombification though.
It sucks that webusb is cjome only, but there are definitely at least a few projects using it.