Why no support for TCP Sockets in JavaScript

... but what is the issue with providing a socket API to allow interacting with existing protocols?

This is not a restriction of the language itself but of it's use inside the sandbox within the browser. Just imagine that a script somewhere on the internet gets loaded into the browser and could from inside the browser access every computer reachable by the browser with arbitrary protocols. You could easily misuse this to send spam through a companies internal mail server or attack/misuse other internal and external resources.

Which means there must be some restrictions in place and the different sandbox environments for the different language runtimes provide different kind of restrictions:

  • With flash the target host must explicitly allow access to by providing an appropriate socket policy file. This is similar to the mechanism within HTML5 CORS.
  • Untrusted Java applets are limited to communication with the host providing the applet.
  • And with JavaScript inside the browser you can talk to almost all sites, but you are limited by the protocol you can use, i.e. HTTP (restricted by CORS) and WebSockets.

I'm not sure what socket API access a Flash object provides, but there are very good reasons to not allow plain TCP or UDP (much less any other kind of) sockets in JavaScript.

The biggest one, probably, is that you're basically providing a way to bypass firewalls if you do that. Every service on your machine that listens on loopback network sockets, normally unreachable by external attackers, can now be attacked from the browser. Every machine on your network, normally isolated from the Internet by your gateway and firewall, can now be accessed or attacked by Internet code.

There are other reasons, too. Port scanning and DDOS attacks become much easier when browsers can do them without so much as a plugin (yes, browsers can attempt to launch DDOS on HTTP(S) servers, but they could be much more efficient with lower-level sockets). Network worms (especially those that only a small proportion of machines are vulnerable to) can propagate much faster when everybody who views an ad on a popular website starts sending out attacks, instead of just those who actually get infected.

Websockets exist to give a way to do socket communication with things that explicitly want to communicate with a browser that is running untrusted code. The typical Internet server is similarly hardened, expecting malicious clients of all stripes. The problem comes from services that are not expecting malicious traffic, because they're only reachable by trusted clients. JS-controlled sockets would totally break that.