RFC 6455, "The WebSocket Protocol", December 2011Source of RFC: hybi (app)
Errata ID: 3473
Publication Format(s) : TEXT
Reported By: Adam Rice
Date Reported: 2013-01-31
Verifier Name: Barry Leiba
Date Verified: 2013-02-18
Section 4.1 says:
2. If the client already has a WebSocket connection to the remote host (IP address) identified by /host/ and port /port/ pair, even if the remote host is known by another name, the client MUST wait until that connection has been established or for that connection to have failed. There MUST be no more than one connection in a CONNECTING state. If multiple connections to the same IP address are attempted simultaneously, the client MUST serialize them so that there is no more than one connection at a time running through the following steps.
It should say:
2. If the client already has a WebSocket connection to the same IP address and port pair, even if the remote host is known by another name, the client MUST wait until that connection has been established or for that connection to have failed. There MUST be no more than one connection in the CONNECTING state for any IP address and port pair. If multiple connections to the same IP address and port pair are attempted simultaneously, the client MUST serialize them so that there is no more than one connection at a time running through the following steps.
The original wording makes it ambiguous whether distinct ports on the same host are considered distinct for throttling purposes. The first sentence implies that the throttling should be applied per (host,port) pair, whereas the final sentence implies it is only based on IP address.
Implementations of both interpretations appear to exist in the wild.
I propose disambiguating in favour of the (host,port) interpretation, because the host-only interpretation allows for a potential denial-of-service attack targeted against hosts which drop packets to unused ports.
For example, an attacker from a different origin can create several hundred WebSockets to "wss://google.com:81/". Each one will attempt to connect in serial, and take tens of seconds to time out.
If the user then attempts to use an application which legitimately uses a WebSocket to "wss://google.com:443/", then due to the throttling to google.com it will not be able to connect until all of the attacker's connections have timed out.
The user will perceive that the legitimate application is malfunctioning, since there is no visible sign that they are being attacked. From the server end, the attack is only apparent in the firewall logs. The actual rate of SYN packets dropped will be small and unlikely to trigger an alert.
On the other hand, with the (host,port) interpretation, connections to google.com:81 do not block connections to google.com:443, and this attack is completely ineffective.
=== Verifier Notes ===
The subsequent paragraph already indicates what must be done in the case where the IP address cannot be determined, so this change should not create any difficulties in the case where the connection is tunnelled via an HTTP(S) or SOCKS5 proxy.
A separate concern has been raised that this section creates problems for WebSocket proxies and non-browser clients. That issue cannot be handled without changing the meaning of the text, so it would have to be dealt with in a document update.