Why can't we have raw UDP in JavaScript?
computerenhance.com
computerenhance.com
- 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.
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.
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.
Why can't it?
https://developer.chrome.com/blog/private-network-access-pre...
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.
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.
IPv4 has defined 10/8, 172.16/12, 192.168/16 as site-local (or internal). IPv6 has similar concept with fec0:/10
(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)
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.
Also see DNS rebinding attacks: https://unit42.paloaltonetworks.com/dns-rebinding/
Here's some typical cases of csrf based vulnerabilities: https://seclists.org/fulldisclosure/2015/Mar/49 https://www.ciscozine.com/cisco-linksys-wag54gs-csrf-change-... https://www.arubanetworks.com/assets/alert/ARUBA-PSA-2021-01...
Remember, the S in IoT stands for security!
OPTIONS requests only happen for cross-origin requests. With DNS rebinding, there are no cross-origin requests, so there will be no OPTIONS requests.
1. You have the victim user open a tab to your page at attacker.com .
2. After the page loads, you change the DNS record for attacker.com to make it point to 127.0.0.1 .
3. Javascript on the page makes requests to attacker.com and can now read and interact with whatever servers are running on the victim user's machine.
Alternatively use 192.168.1.1 to attack the victim user's router.
This attack will be blocked if the victim servers check the Host request header. Often they don't.
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.
> If DDoS was the concern, just require that UDP packets be sent exclusively within the same domain as the originating code.
So you couldn't do any of these things.
> And again - what actual benefits would there be to raw UDP access? The article is very light on specifics.
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.
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.
(If some implementations have high processing latency on top of the network latency, this can be fixed without changing the protocol).
Ship sailed, horse out of barn, etc etc on this point.
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).
You mean when Google implemented it in their EEE fork of the web.
Yes, it works pretty well using established technologies in the browser already.
There is no HTTP headers for raw UDP.
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.
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.
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
> 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 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.
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.
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.Maybe if the "large company" he talked about was the NSA/FSB/MI6/Chinese Intelligence it would make sense.
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...
That's doable on Android, though security sensitive people won't install a random APK found on the web.
And signing a binary on windows is doable, but rather expensive.
Either you get a proper WebRTC implementation like Google's which is huge and does a ton of other stuff, or you talk to another browser peer to peer.
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.
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...
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
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.
We have HTTP, WebSockets, and WebRTC.
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.
sudo setcap cap_net_raw,cap_net_admin=eip /usr/lib/firefox/firefox
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.
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.
True, but a raw socket does require privs.
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.
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! :(".
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.