Browsers don’t let you send raw UDP packets for the same reason they don’t let you send raw TCP packets: because devices in home and business networks implicitly trust many packets coming from inside your network. A short list of things you could do with raw TCP / UDP capabilities:
- Reconfigure a user’s router (if they have the default password)
- Print to a network printer
- Poison the home network ARP table
- Various network level DOS attacks (ICMP echo flooding attacks, etc)
- Control smart home appliances
- Access network shares
- Insanely invasive fingerprinting (including figuring out the make and model of other devices in the user’s house).
So no, it’s a terrible idea. I don’t want webpages printing things, turning my lights on and off or knowing anything else about me.
If you want the benefits of UDP through your browser, use webrtc or wait for HTTP3 or Webtransport.
The author seems to want the OS to have no knowledge or involvement in the network protocol, for unknown reasons. But they obviously think the user’s web browser is fine. From the point of view of a web application, what’s the difference?
And again - what actual benefits would there be to raw UDP access? The article is very light on specifics.
CORS doesn't generally care if the final IP was resolved from localhost or example.com (or any other DNS entry), if the host doesn't have the right response to OPTIONS requests, you won't be able to communicate with it in the browser, unless your on the same IP/DNS as you're trying to talk to.
There are CORS bypass techniques, CSRF exploitation via methods which are not checked by CORS such as img tags, and common exploitable misconfigurations (and maybe you can race the preflight check with dns rebinding attack?) - but the question of local address handling playing a part was the main point of my response.
But that requires you to load the page resource from that origin already, so if you're already in control of it, what would you want to do that you couldn't already?
I mean it's nowhere as bad, and for legacy stuff usually CORS/SOP helps.
New implementations that use websocket as their root (mostly for web browser compatibility) seem to take security more seriously out of the box, I use a couple apps in my day-to-day which expose APIs over Websocket and don't trust by default.
- Vtube Studio has a auth dialog that pops up on first connection you must accept before commands are executed
- obs-websocket by default requires a password to be used.
There's always outliers sadly, for example "beefweb" (Foobar plugin) has auth but it's not enabled by default.
Every one of your threat vectors listed would be prevented by appropriate browser origin policies (which already exist for existing protocols).
The only slight exception might be fingerprinting, as new APIs always extend this surface area somewhat, but not in the way you're describing (enumeration of local network devices) given aforementioned origin policies.
Browser origin policies are difficult to use to protect something that listens to an IP address rather than a host due to DNS rebinding. This can happen implicitly if the victim service doesn’t check the host header. This is already a big problem with HTTP but with UDP or raw TCP there is no host header so anything that trusted the network would be broken.
How do you enforce an origin policy on raw TCP? CORS/SOP are heavily built on HTTP semantics, and you cannot easily map this back to raw TCP sockets. Even just allowing a TCP socket to the page origin's IP address is unsafe, because it might be a CDN and allow skipping CORS for other sites.
True, it wouldn't be as straightforward as HTTP, as there would need to be new semantics (e.g. a handshake protocol for locally-cached IP allowlists or similar), but I guess my general point here is that the gp cited a large list of vectors that are all essentially the same problem & could be tackled with a single targetted (very conceivable) solution.
Any new such solution would of course come with its own incorrect-implementation dangers - increased attack surface is increased attack surface. The sibling commenter rightfully points out these are still a potential issue with HTTP (servers not checking Host). But spec-wise a solution is still very doable.
The article states that, just like microphone access, users would have to approve UDP access and it would only be allowed to a single server. I think that solves your router/printer/etc issue?
> what actual benefits would there be to raw UDP access
Author appears to want to control the whole stack. Based on their calling out HTTPS and friends as way too complex to implement. This is the HandmadeHero author afterall.
And the standard answer to “why UDP?” is “required for game dev”. TCP is a non-option for many types of games.
The connectivity to any address/host would be a bad idea, what about restricting only to the same host of document's origin.
Edit: Java's applets used to have the bog standard TCP (and UDP) and since late 90s. While Java/applets were a security nightmare, as all of them run in the same process and the impl. of SecurityManager (and its checks) was not up to the task [along with various deserialization exploits], the connectivity was not an issue.
Same-origin isn't sufficient, because an attacker who controls the DNS resolution of their domain can create a DNS record with the same origin that points to an internal target address. (And before you ask, no, the browser can't reliably distinguish internal from external IP addresses.)
If the attacker is restricted to performing HTTP requests, then things like the Host and Origin headers allow servers to defend against this. If you allow web pages to make raw TCP connections, those protections evaporate.
And I'm pretty sure that if Java applets allowed raw TCP, they would have had the same vulnerability; it's just that typical attackers weren't quite as sophisticated in the 1990s.
How would it? IP has no concept of “Internal IP addressees”. There are reserved private address spaces, reserved local address spaces, and reserved public address spaces.
Both the private and public address spaces can be used for “Internal Addresses”. The fact that we frequently use NATs and private address spaces to work around IPv4 exhaustion does not mean you can expect all “Internal Addresses” to be in a private range.
The second you start using IPv6, or your in an old internet environment like a University, the DoD etc who has huge IPv4 address space, then you’ll find every machine has a IP address in a public range, there’s just firewalls preventing inbound connections, but you can’t easily detect those firewalls from the client.
Those v4 examples are really ambiguous addresses, orthogonal to local-ness. Same goes for ambiguous addresses used in CGNAT. More importantly, the complement: you don't know that a non-rfc1918 address isn't local. This is important because the latter is actually the definition the proposed "only allow non-local" use case would require.
(Also fec00::/10 was deprecated 15+ years ago - there are still some special prefixes like ULA but for IPv6 their usage is marginal since there's no shortage of normal address space)
Only if you completely ignore the preceding discussion about same-origin policies, and how browsers can’t provide a guarantee that a host at particular IP address is a public system or an internal-only system.
A host with an IP in a private range might always be internal, but a host with an IP in a public range isn’t always external. And as the stated goal is to avoid browsers being a trampoline to attack internal equipment, not being able to guarantee that a particular host is an internal host is problematic.
Many organizations use “real” publicly routable addresses on their hosts for IPv4 (rare) and IPv6 (common), without NAT devices. Stateful firewalls don’t require the use of NAT.
That's a defense-in-depth measure; it can't be relied on. The exact same attack can be used against targets on a corporate network that doesn't use the RFC1918 address ranges.
I wouldn't associate those mainly with corporate networks. The prevalence of RFC1918 use is an artifact of IPv4 and address shortage. IPv6 usage is already at 40% today.
Also hosts are increasingly multihomed, devices are likely tohave 2-3 network interfaces, with v4/v6 addresses for each. VPNs are run in "split tunnel" mode where some traffic goes via VPN and some not, so both un-tunneled and tunneled traffic is allowed simultaneously, etc.
HTTP has Host and Origin. Raw TCP/UDP do not. “The same host of document’s origin” can host any number of completely unrelated websites/services thanks to vhosting.
Restricting origins doesn’t work thanks to a fun little trick called DNS rebinding. Let’s say you get the user to browse your site, say, attacker.com. They lookup your DNS and see that it’s 1.2.3.4, with a TTL of (say) 5 seconds.
Five seconds later, the user’s DNS cache entry expires. Your page triggers a new request to attacker.com. Since the TTL has expired, they do another DNS lookup - and you serve them a different IP address, say, 192.168.1.1. Now they make a new request to that IP believing that they’re still accessing attacker.com.
With HTTP requests there’s at least the possibility of detecting these attacks via the Host header (even if that doesn’t usually happen in practice). With raw UDP, however, the attacking packets would be indistinguishable from legitimate ones.
This could be resolved by having the browser cache the IP and refresh it for child operations. Sure, this is a change in current behavior - but for a new feature like UDP, or arbitrary TCP, it could work.
As others have pointed out caching the DNS past the TTL is it’s own security problem.
I think the fix is actually to disallow resolution when the TTL is too short (eg <1 hour) and refusing new outbound requests once the IP address changes without a refresh of the page. However, I’m not a security / network expert so there may be a critical flaw in that idea.
Have a page load up a script from <nonce>.relevantdomain.tld, once the script sends back a packet to <nonce>.relevantdomain.tld, have the dns settings change subdomain to 192.168.0.1, and then etc
the war between safe things and unsafe things is endless, so we shouldn't be adding a massive unsafe thing and then bodging patches onto it to make it "safer" than completely unsafe
> It seems like writing game netcode without setting up a WebRTC server should be reason enough.
this begs the question - is the browser really the right platform for a game where netcode like that is needed?
Why make the browser even more complex, when the original design of it is meant to only display documents? If we keep going down this road, you'd end up with an operating system inside the browser.
> If we keep going down this road, you'd end up with an operating system inside the browser.
Arguably, we're already there. I stopped pretending the web wasn't going to be the common platform of the future when WebUSB dropped and I learned you can root a Nintendo Switch from Chrome OS. Without the Linux part.
If you build something today, without too many resources backing you up, and you want it to run anywhere, you build something that resembles a PWA with Electron wrappers. (resembling because it could also be something like Flutter).
If we're going to have games and audio on the web, which we do, we could at least have them work without mountains of additional latency or WebRTC servers.
I would also like it if web sites would display documents, allow the browser's "find" feature to work, and not use "responsive UI" to delete the form that I'm halfway done filling out when I resize my window, but I don't think my preferences have much weight here.
WebRTC is peer-to-peer so there's no additional network latency from the protocol. There's the TURN fallback for when the participants can't reach each other, in which case bouncing through a proxy is the best you can do anyway.
(If some implementations have high processing latency on top of the network latency, this can be fixed without changing the protocol).
Can you explain how "require that UDP packets be sent exclusively within the same domain as the originating code" does not address any of that comment's concerns, or are you just nitpicking?
evil.example.com can easily set up a subdomain such that 192-168-2-44.home.evil.example.com resolves to 192.168.2.44, so requiring that UDP packets be sent exclusively within the same domain as the originating code doesn't help at all.
Same domain is pretty meaningless until all browsers mitigate DNS rebinding, which as far as I know they still don't. And even that would presumably only help with private IPs.
Hide it under prompt and that's about it. Alternative is that user will install some sketchy exe file which will do the same, but without any prompts. Browser could make it more secure.
"If you were a large company with significant academic and engineering resources, you might instead want to design your own private secure protocol that:
Uses encryption you control, so it cannot be bypassed by hacking the certificate authority,
Uses UDP to avoid having OS connection state on the server side, and
Uses a well-designed, known packet structure to improve throughput and reduce security vulnerabilities from HTTP/TLS parsing."
I think at this point they would have done well to explain why WebRTC data channels are not usable or incrementally fixable for the purpouse. It's SCTP tunneled in DTLS over UDP. Missing is just the home brewed encryption requirement which would generally be a no-no in security engineering practices.
Fully forgetting that what ever they roll has to have state on server side, just this time in the server software... Not solving too much...
And then forgetting the nice stuff TCP offers like in-order guaranteed delivery...
Both which is needed for most sensible encryption schemes. And doesn't really get away from needing a PKI... Or then you could just grab a connection before it is formed. If you can MitM HTTPS you can MitM anything else...
one half of me is crying and clapping knowing it'll let me do more cool web stuff. The other is cowering in fear, knowing full well this is just one more step in the web cabal's master plan to run a full virtual pentium 3 with soundblaster and ATI card just so i can read the news
Unfortunately that restricts your platforms a lot, and even for the platforms that this reasonably works for, requires a lot of porting and testing effort (or you need to settle for a single narrow target platform).
Yeah and its an absolute PITA to set up, and a nightmare from the ops perspective, I'm not even sure what even are you supposed to use on the server side.
If you’re using WebRTC data channels in a client server config then infra is no more complex than a regular setup because the server will almost certainly have an external facing IP address.
People should really try using WebRTC as well because you can get the full pipeline setup for a toy demo in a couple of slow days. I did whilst also writing my own signalling server in Go without having used Go before!
It’s certainly not any more complex than rolling all the stuff the article is talking about on top of raw UDP.
I see just too many issues. Including things like NAT having to guess what to do with your unique UDP packets and then some users complaining why your site doesn't work...
Also generally rolling your own anything isn't that great idea from interoperability to security concerns. And just imagine this multiplied to everyone copying some blog post who knows from where...
As a person who worked on the original web socket spec - it's because many networks run "deep packet inspection" routers, etc (to protect the network or some such), and those routers are almost universally badly written.
There have been many cases where those routers can be compromised by sending specially crafted content. That's apparently something that hit Java applets, presumably ActiveX (though with activex that is surely on the lower end of the security issue spectrum?).
Because of the nature web sockets providing much more control of the actual bytes on the wire from a browser it was necessary to "encrypt" the bytes. The goal isn't to secure the content, it's to make it so attacker JS can't control the byte content - the "encryption" key is literally prepended to the data being sent so anyone sniffing network traffic can "decrypt" the WS data.* From JS running on a webpage this is completely transparent (or is that opaque?) because obviously if the web content knew the key material they could modify their data to get the correct bytes again.
This is one of the things people forget when asking for browsers to provide features: it's not just "what can I use this for?" but "what can a malicious actor do with this?". Because the threat model for a browser is not the same as an app - browsers can be trivially made to load and run arbitrary JS - Ad networks are notorious for it, but unending websites make it possible. One of the things that make the web a great and amazing thing is that I can go to any website, and not worry about it doing anything to my computer (and with the exception of chrome) browsers also try to make malicious behaviour like spying on you hard as well. Yes there are security bugs that can be exploited, but there's a difference between a security bug that can be fixed, and a literal specified attack surface. *
* To actually protect data you should be using TLS, but you knew that right?
* Fun story, there was a version of the SVG standard (or a draft? it was a long time since I was on that committee) that provided raw socket access
We also don’t have raw TCP or ICMP in a web browser. It’s probably for very similar reasons.
My guess is that there is no strong enough demand for such low levels network protocols in major web browsers. It is not worth the risks, and the costs, and the complexity.
raw ICMP requires root permissions. For instance 'ping' runs with elevated/root permissions. "Raw" TCP is a mystery, though. WebScokets are like, ehh, fine, whatever - it's a framed stream protocol.
We have raw USB in a web browser. I can access my USB security token from the browser right now. I can access my raw keyboard USB connection from the browser right now. How is network access have less demand that raw USB? Even simple thing like mail client can't work in browser without using third-party server (and sending your password to that server). Same about ssh client, etc. A lot of apps are currently impossible in browser or security nightmare because of this artificial restriction.
Raw USB is a Chrome-only extension, Safari and Firefox don't support it because it's an awful idea. Even so, it's much easier to make a meaningful permission dialog for USB than for a TCP or UDP connection. With USB there's a limited set of devices you can connect to, and they somewhat human-readable names or vendor IDs that can be translated into names, and there's no way to do something like a DNS rebinding attack with them since the browser can detect when the device is unplugged.
It is entirely possible to make a secure SSH or IMAP client in the browser, just proxy the encrypted data and do TLS or the SSH protocol in Javascript.
I suppose one could do this but then each OS will have to set flags on the browser executable and there is a whole can of security worms that opens. In Linux one could use
This could and probably should be automated in firejail or bubblewrap rather than the installer. Does this exist for Windows or Mac?
If using AppArmor or SELinux rules would need to be created unless Firejail is managing the rules on the fly. Then the browser would need to test for the capabilities and give some meaningful log in the web console because a way to debug this is considered good ettiquite. Then one would need a library or API in the browser that knows how to open raw sockets which means getting all the major browser developers to agree on a standard.
Thinking long term there are going to be security auditing tools that will detect the binary has non standard setcap modes meaning that browser developers would have to reach out to all these companies to get on the same page otherwise corporations will have some knee-jerk reactions.
UDP is not a privileged protocol. You don't need any capabilities to speak UDP. It's used by web browsers already for HTTP/3 as TFA mentions.
But also, apps needing additional capabilities is rather common and handled by most any package manager that's going to be providing you a browser. Chrome in various configurations ships with a `setuid` binary to implement their sandbox, for instance.
Casey is a game developer, his use-cases are probably games targeting the browser and how it would be possible to improve their communication with external servers.
*is a game developer with a particular focus on "RETVRN TO TRADITION" where anything that isn't super lean-and-mean is bloated and inefficient and ridiculous, and only exists because web developers are misguided, miseducated, etc. WebRTC could do what he wants, but then he'd have to build a WebRTC->pure UDP gateway.
I can sympathize, but, even in the original discussion on Twitter it's clear he is ill-informed of the relevant security fiascos that made all these complicated protocols necessary, or the messy legacy constraints they must operate under. Infrastructure is not magic, and tying together e.g. application-level concepts with DNS-level concepts would be a recipe for misery IRL.
I also find it funny he considers the string/text-based parts of HTTPS to be unworthy of a secure protocol, when in fact, the whole reason that approach is considered so dangerous is because of programmers with his attitude who underestimated the difficulty of secure parsing. The niche of "LangSec" is all about solving this problem properly by treating input processing as a formal parsing problem with formal grammars.
Is it really necessary to attack Casey with this two bits sarcasm? You can disagree and still be polite for the sake of me taking you seriously, if not for his.
It is really PITA. We're making a service which works with various devices. Most devices work over serial, so WebSerial makes it painless. But there are some devices which work over TCP/UDP. So we have to install our software to user computer, install our CA certificate into user store just to be able to talk to TCP/UDP from the browser. Much security.
Unless you support Safari you don't need to add a cert, http connections to localhost are considered secure connections in Firefox and Chrome and basically every browser besides Safari, so you can connect to them from an HTTPS site with no mixed content issues.
But nooo, I also want to send raw Ethernet and IEEE 802.11 frames from the browser! /s
There's always a baby that will cry for more. People have been begging for raw socket access and other "I just can't get my head around this"-shortcuts since they wrote their first "Hello World!", TODO-list or guestbook API. There isn't really anything you couldn't solve with the things there are now in every browser. What would UDP bring to the table other than more work to deal with it in that regard? This is nothing about innovation or technical limitations. This is just another case of "B- b- but I want it my way because that's how I always did it! :(".
Ah, the "wave off as strawman"-argument. HN's favorite meme. (I guess that's why you edited it out?) Any real counter arguments, though? Even the article fails to make a point other than "UDP can be as secure as HTTPS!" which no one really ever argued about other than the article writer itself to make a synthetic point about it.
I edited out the word "strawman" almost immediately after posting since I (correctly) realized it could become a fixation point in your response that you would use to dodge the question.
Small point of order, but shouldn't this be retitled to, "No really, why can't we have raw UDP in the browser?" since you definitely can do UDP in "JavaScript"?[0]
At this point the primary operating system globally is Chrome. It is an overlay operating system, but still should go in that category.
The web platform has APIs for just about everything else at this point. Even USB.
The main reason we don't have UDP, aside from some security challenges, is probably that it actually really opens up possibilities for decentralization via direct P2P connectivity, which could rapidly decrease the control and profits of the big internet companies. Yes there is WebRTC but that is not quite the same and specifically is scoped inside of the browser.
Ordinary UDP support would invite things like libp2p to be ported. Then people bringing in entire decentralized applications using web assembly.. and finally people will eventually realize they don't need a bloated overly complex browser and start using lighter weight platforms built in web assembly extended with things like UDP and cryptocurrency support etc.
That will also pave the way for script/app free information browsing as it becomes popular to break out of the Google platform.
So there are billions of reasons for Google to suppress UDP. They would never admit it though.
- Reconfigure a user’s router (if they have the default password)
- Print to a network printer
- Poison the home network ARP table
- Various network level DOS attacks (ICMP echo flooding attacks, etc)
- Control smart home appliances
- Access network shares
- Insanely invasive fingerprinting (including figuring out the make and model of other devices in the user’s house).
So no, it’s a terrible idea. I don’t want webpages printing things, turning my lights on and off or knowing anything else about me.
If you want the benefits of UDP through your browser, use webrtc or wait for HTTP3 or Webtransport.
The author seems to want the OS to have no knowledge or involvement in the network protocol, for unknown reasons. But they obviously think the user’s web browser is fine. From the point of view of a web application, what’s the difference?
And again - what actual benefits would there be to raw UDP access? The article is very light on specifics.