27 Comments

My sense is that the game they are playing is blame management and plausible deniability.

Without https, it becomes plausible for banks and other websites where security is paramount to blame the web standards for lacking a way to secure connections when they leak sensitive user data.

So what the committees and browser vendors really wants is a way for the browsers to easily know that all connections with this site are "secured". Now, if information leaks, the blame is solely on the site operators.

Currently they can do this if the site uses https.

If you introduce UDP to the mix, and tell them "I will encrypt the packets myself", then the browser has no way to tell whether the connection is secure or not, so they will default to telling the user that this website uses an insecure connection.

This would not be so problematic, except I think they want to eventually deprecate non-secure connections.

Efficiency and simplicity is the last thing they care about. They will only care about it when someone demonstrates the existence of a clearly superior web application that cannot be implemented without a certain feature. I think this is why wasm got standarized.

Expand full comment

Create your own client app. This is very much trying to fit a square peg into a round hole.

If you want to, you can even give your client app an address bar, and let others use your app for their servers. Then you won't even need to touch html or css or JavaScript.

Expand full comment

>The owners of ddosfuntimes.com can go ahead and set the IP address in their DNS records to point target.ddosfuntimes.com at any server they want, and they will receive all the XHR traffic from every browser that visits the page. And to the best of my knowledge, there isn’t a damn thing the target can do about that.

The attacks people are concerned about are about more than just DDoS. It's e.g. about impersonation and theft-of-service. You shouldn't be able to mimic an existing site and trick people into using it. You also shouldn't be able to use resources from a server you don't own. This is web security 101.

This is not possible in your outlined scenario: you can't make an HTTPS connection to `target.ddosfuntimes.com` because the hostname wouldn't match. So the only thing you'd be able to do is make a lot of failed HTTPS connections, which are aborted early. This would also be preceded by a DNS request for a hostname that can be flagged as suspicious (i.e. potentially blockable at the ISP level). So it is in fact possible to detect and filter out early, somewhat. This is exactly what services like CloudFlare are for.

>Furthermore, since the browser already allows the page to send as much HTTPS data as it wants back to the originating site, one could optionally allow any site to send UDP packets back to its own (exact) originating IP without asking the user.

The HTTP origin policy is actually about more than just IP, it involves the port too. You can call this paranoid, but nevertheless, that's the rule. So you'd either have to require that TCP and UDP ports match, or, you'd need to relax the restriction, or introduce some port negotiation scheme.

>So unless I’m missing something, XHR already allows you to target any website you wish with unwanted traffic from anyone who visits your site. So why the concern about UDP?

Not only are there security concerns beyond DDoS, but there are also practical concerns due to e.g. NAT and crappy airport/hotel wi-fi, which people generally expect to work. There are also privacy concerns with VPN users (and users who live undemocratic regimes), e.g. the ability to discover somebody's true IP address.

In fact, if you want a UDP-like protocol that satisfies all the above, you pretty much end up with WebRTC, which has semi-viable answers for these issues, runs on DTLS, and has been used to actually run complex video/audio conferencing in the wild.

I should add, you made a few blunders in your questioning on Twitter, and continue to do so here, so you are not doing yourself any favors by adopting a demanding attitude because you don't get the detailed security research you want _right now_. Like it or not, these are the kind of things professionals are generally paid to work on. They take a lot of time, experimentation, verification, and validation. So if you get low-level explanations on Twitter, without the detail you want, that's because you're sounding like somebody who needs to have the basics of the field explained to them.

Btw:

>ridiculous things in it like arbitrary text parsing, which no one in their right mind would ever put into a “secure” protocol

I'm not sure exactly which part you find so ridiculous—feel free to elaborate–but there's plenty of precedent of horrid binary encodings which left destruction in their wake (e.g. ASN.1). They are harder to work with, harder to parse, harder to extend (see: IPv4), and harder to verify by humans working with them. And let's be fair: the main reason "arbitrary text parsing" is considered a minefield is because people were stupid enough to keep doing it with handrolled code calling the C standard library, instead of verifiable tools like grammars and parser generators, because of a misplaced sense of "I can handle these footguns".

The trend you see these days is binary encodings with a canonical 1-to-1 text representations, which seems like the best compromise between accessibility and efficiency.

Expand full comment

Never stop writing. I love to read your stuff!

Expand full comment
Oct 26, 2022·edited Oct 26, 2022

The last thing I want is for a random web page or iframe/ad in my browser to have the ability to spoof packets coming out of my PC to look like something unexpected. Giving out access to UDP is a footgun, except someone else will be very deliberately aiming the gun at your feet and everyone else's.

Expand full comment
Jul 18, 2022·edited Jul 18, 2022

Any custom encryption method will be impossible for the browser to verify. You could use some protocol to claim that you've encrypted your UDP API, but the browser wouldn't know whether that is true, or whether your implementation is reasonable.

This means no padlock icon on sites using UDP, and probably "WARNING: This connection may be insecure!" too.

Sites care about broadcasting their security to users. Which site would ever choose to use a feature which is going to warn the user that their site may be insecure?

Browsers care about warning their users in situations which are potentially dangerous. Why would they show a reassuring padlock that they can't verify, or implement a feature which gets users into the habit of clicking "continue anyway" on warnings?

It's not a technical hurdle to a secure implementation, but it's a hurdle to a secure implementation with a reasonable user experience. Nudging users towards secure behaviour is just as important as technical security. The existing padlock system isn't perfect, but it's a lot better than nothing.

Expand full comment

Was a hypothetical WebUDP API even considered and/or rejected by WHATWG/W3C/etc?

The only *technical* objection to handing out raw UDP to web apps that I can think of is that it partially bypasses same-origin. It's important to note here that both the port and protocol constitute part of the origin; so for example http://example.com:80 and https://example.com:443 would be separate origins that cannot talk to one another. In fact, if a website were to be using custom ports, then http://example.com:8080 and https://example.com:8080 would also be separate origins.

These setups are all entirely crazy, but they are also historical legacy. Some badly-written webapp *somewhere* relies on the fact that browsers will isolate different servers on the same machine from each others' client traffic.

In fact, digging deeper into the historical legacy of the TCP/UDP spec, ports below 1024 are supposed to be admin-privileged, while anything higher is available for all users. So if same-origin didn't consider ports, then any user on the same machine as the server (a common arrangement in the early days of the web) could set up example.com:1337, and anyone linked there from example.com:80 would be sending all their :80 login cookies to :1337.

*Modern* servers don't look like this, of course. You'll have example.com:443, 0db8.net:443, ietf.org:443, and all sorts of other machines all being hosted out of one set of anycasted Fastflare or Cloudly IPs. This means that we have to tell the machine at the other end what domain we expect it to pretend to be with a Host: header or SNI header, so that requests get routed to the right vhost.

If we granted raw UDP to webapps then both the old style "services and shell accounts" and modern "vhosts all the way down" approach to configuring web servers would have new security concerns, because we're relaxing same-origin. All the existing Web-specific socket protocols are there to maintain the "protocol, domain, port" origin rules by bootstrapping sockets off of the already well-understood HTTP and HTTPS protocol headers so that they *don't have to change those rules*.

Now, would *relaxing* these rules for raw sockets hurt things? I'm not sure. But the benefits are really vague. Our security model is more rational, yes, but we made it make sense by weakening it. We can support really old legacy protocols that nobody should be using now - e.g. Ruffle could faithfully emulate Flash's RMTP and XML sockets using your raw sockets proposal. And you could theoretically roll your own HTTP stack and crypto for whatever reason.

On the other hand, every time the same-origin policy is relaxed even a little, bad things happen without a *lot* of foresight. To beat up on Flash again, it handled cross-origin requests using a special crossdomain.xml file at the root of a website. Because it was "in-band", so to speak, webapps with upload forms that didn't know about these files could be tricked into hosting them, for starters. Worse, it did not send any identifying header that would tell you if a request was cross-domain, so permissive cross-domain policies would leak sensitive data. Compare it to HTTP CORS: the browser pre-flights every request and the server responds if it's allowed. The actual cross-domain request itself is also properly marked with the origin, so you don't even need to restrict any cross-domain access. You can just allow all requests, check if each request is cross-domain and redact sensitive information if so.

Raw sockets feel less like HTTP CORS and more like crossdomain.xml. There's no mechanism in TCP or UDP for the browser to say, "hey this request came from a script on example.com:80"; and without that information non-HTTP services will get confused and get hacked.

Example:

Let's say Cloudflare has a secret management service on UDP port 4000 that lets their operations team debug broken production servers. Of course, this is dangerous, so it's all firewalled off to a VPN that operations only connects to when they are debugging machines.

You are a hacker. You set up notevil.net:443, put it behind Flarely, and buy the premium service package with all the extra support stuff in it. Then, after a week or two you ask support to look at your website. The website is "down", and because you're a high-paying customer one of the ops team is dispatched to take a look at the site.

Oops. Raw sockets means that notevil.net:443 can now access that secret management port on :4000 *from within the FastCloud operations VPN*. We've already broken through their corporate firewall with just normal web standards. It does not matter if the hosting provider "shouldn't" have this kind of management setup; it does not matter that our security model is uneven and prohibits this tier of attack but allows another. The same-origin restriction is a strict promise that we wouldn't allow this to happen and existing security systems are built around it.

Expand full comment
Jul 7, 2022·edited Jul 7, 2022

> But at least it exists, and perhaps if adoption continues to grow, eventually it will be possible to require HTTP/3 without losing a significant number of users. For now, it’s only something you can do on the side - you still have to have a traditional HTTPS fallback.

It's estimated that 75% of browsers (well... I guess user agents) on the net support HTTP/3 acording to wikipedia

> Which brings us to the third item on the list, and the real sticking point. As far as I’m aware, no current or planned future Web API ever lets you do number three. There are many new web “technologies” swarming around the custom packet idea (WebRTC, WebSockets, WebTransport), but to the best of my knowledge, all of them require an HTTPS connection to be made first, so your “custom packet” servers still need to implement all of HTTPS anyway.

Right, WebTransport over HTTP/3 is an option.

Your theoretical "I am writing a UDP library but want to isolate my HTTPS stuff somewhere else" situation... I mean beyond the fact that there are many options to strip away the abstraction, if you're writing a custom UDP protocol but are afraid of HTTPS, HTTP/3, that is a bit odd to say the least!

Now for technical concerns:

TCP is, of course, TCP. Ordered, etc. And so if you're sitting there with HTTP over TCP, well... firewalls etc are very straightforward. There is a very limited amount of things going on, so it is easy to control. UDP is completely the opposite, as you really can only do destination-based filtering.

So you only have source and destination as an option. One option is to say "ok you can't do cross origin UDP". In that case there's the reality that you control the client and the server, so to speak, so... just use WebTransport! You have your option there.

Another scenario, where you say "we'll allow all cross-origin UDP. Users can say accept/deny". Some random site decides they don't like you, and add some JS to DDOS you. They ask users to accept (and users do it cuz it's one of those websites). Users end up DDOSing you. The "approve/deny" flow works well for when you are the potential victim, but in the DDOS model you are not "consenting".

You might say "well, they can do that from their machines by dowloading software", and you are right.

How is this different from the image tag? The magic of HTTP makes actually filtering out stuff real straightforward. XHR stuff is different from handling black box UDP. It's actually easier, and because there is a protocol it's much easier to cut things off, not wait around while receiving garbage, etc. And middleware can also handle it on their end. Enterprises have networks to run.This is how Cloudflare exists and does its stuff/reject connections real easily. Raw, black-boxed UDP? All off the table.

You could make a protocol off of UDP that does a bunch of stuff to make this easier. But now... what? Are you just making TCP? You're gonna make your own magical protocol to avoid implementing WebTransport?

So in that case... you would probably want to establish some handshake for the connection. You might want some origin-based tokens similar to how people set up CSRF tokens for POST. And there's all these other concerns.

And now you have ended up adding some layer over UDP anyways!

Your claim is that you can't just go raw UDP mode in browsers. This is true. But WebTransport exists and you can use that to get all the advantages of UDP mode, while also taking advtange of the security benefits of the HTTP protocol.

So serious people will look at WebTransport, and correctly identify that it fits within models they are used to work in, and they can get all the advantages of UDP speed.

So your ask here isn't "let me have access to UDP", it's "let's add a UDP-based API that will make it easier to distribute DDOS-y software and generally create more unauditable traffic and make network QoS harder". Remember, you have access to UDP if you deal with WebTransport! And you might think that's not important. Many people disagree.

The technical claim is that a raw UDP connection that is assumed to have any content is harder to automatically filter out or otherwise manage, but the wrapping cost of WebTransport over HTTP/3 is small enough that browser can offer UDP to users, so long as they are using that.

And, of course, you can give yourself raw UDP in Javascript, if you're using something line Node. You're asking for a raw UDP API inside of browsers.

Expand full comment
Jul 5, 2022·edited Jul 5, 2022

The answer, as always, is "corporate users". Every single big enterprise I've interacted with has some form of HTTPS filtering and/or MITM in place to prevent data leaks (or so they claim). Nobody who does that wants to deal with CaseyCrypt(tm) over raw UDP/TCP.

Expand full comment

At least one problem with raw udp/tcp I see here, is that it is now possible to leak data from private networks/local services (these days CORS prevents most kinds of client requests unless server is configured in a specific way that allows that) .

Expand full comment