Subject: Re: [hybi] Multiple connections serialization and proxies

From: Ian Hickson <[email-masked]>
Date: Tue, 20 Jul 2010 23:14:16 +0000 (UTC)

On Wed, 21 Apr 2010, Wellington Fernando de Macedo wrote:
> 
> A question has been raised in the Mozilla implementation. The spec 
> states:
> 
>  1.   If the user agent already has a WebSocket connection to the
>         remote host (IP address) identified by /host/, even if known by
>         another name, wait until that connection has been established or
>         for that connection to have failed.
>
> However, when the WS is under proxies, we can't leak the host names to 
> the DNS server. In this case, what should be done? I think the spec 
> should clarify this.

Done. It now says that in that case, host names should be assumed to be 
distinct from each other, but that the UA should have an overall limit.

   http://html5.org/tools/web-apps-tracker?from=5169&to=5170

On Thu, 22 Apr 2010, Christian Biesinger wrote:
>
> Note that if you want websockets to be similar to HTTP, it should always 
> use host names instead of IP addresses for connection limits. At least 
> Firefox uses hostnames for HTTP's limit, I'm not quite sure on the other 
> browsers.

Using host names for this particular limit wouldn't work since it would 
mean an attacker could just have a bunch of different host names all 
binding to the same IP to DOS the host.

On Fri, 23 Apr 2010, Thomson, Martin wrote:
>
> So, the only protection against multi-connection-DOS from the one client 
> is to request that the client not have more than one connection attempt 
> in progress at a time.
> 
> This only works if the client doesn't get rejected straight away, 
> otherwise, the round trip time is the only limiting factor, which isn't 
> that great.
> 
> Some (security considerations) advice on what a server might do to take 
> advantage of the client-side requirement would be good.

I've slightly ammended the note in the aforementioned step to mention that 
the server can simply delay before terminating the connection if it wants 
to take advantage of this. It seems pretty obvious though, I don't know 
that we need to belabour the point.

On Fri, 23 Apr 2010, Greg Wilkins wrote:
> 
> My preference would be to enable the use of a single connection
> with multiplexing - so that multiple "connections" would not need to
> suffer the cost of any RTT for TCP, TLS etc. and would certainly
> not need to be serialized with other "connections" establishment.

That seems reasonably straight-forward to support at the application 
layer.

On Fri, 23 Apr 2010, Jamie Lokier wrote:
> 
> Once the number is limited, the bandwidth can be limited by the server 
> itself slowing down responses when it see repeated requests from the 
> same client IP.
> 
> Unfortunately it can't distinguish different clients from the same IP - 
> so clients can DOS other clients if the server does this, which is also 
> a problem.

It seems relatively simple for a browser to rotate amongst the various 
origins that are trying to connect, to avoid this problem being serious. 
The UA could also explicitly announce to the user that one tab (from one 
origin) is being prevented from connecting to a particular server while 
another tab (from another origin) connects to it, especially if the latter 
one keeps getting declined. In practice, though, this is unlikely to be 
that much of a problem -- this attack is already possible today using 
HTTP, and yet is rarely an issue. (In fact the only time I've seen it be a 
real issue is when an origin DOSsed itself, e.g. if you open three tabs to 
the same host and all three try to do a long-lived GET.)

> Therefore clients should identify themselves somehow.  (Clients could 
> cheat, but cheating clients won't obey the anti-DOS requirements 
> anyway.)

The "client" here is the origin, which is already in the handshake.

> Another aspect of client-side DOS protection is at what point is the 
> "connection" considered "established", to permit more?  It should be 
> later rather than earlier in the negotiation process, to prevent DOS 
> against server-side negotiation resources especially TLS.

As far as I can tell, the definition is unambiguous here.

> I favour the server being able to send back a number saying how many 
> more connections are permitted now.  Negotiated flow control, rather 
> than spec'd fixed values (except the first).  There could still be a 
> default, for simple implementations.

That seems like something we should add in a future version, if it really 
is needed. Baby steps, keep things simple, etc.

-- 
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

---

From: John Tamplin <[email-masked]>
Date: Tue, 20 Jul 2010 19:39:12 -0400

> is needed. Baby steps, keep things simple, etc.

Given the lack of extensibility and negotiation, how would it be added in
the future without breaking backwards compatibility?

-- 
John A. Tamplin
Software Engineer (GWT), Google

---

From: Ian Hickson <[email-masked]>
Date: Wed, 21 Jul 2010 22:28:34 +0000 (UTC)

On Tue, 20 Jul 2010, John Tamplin wrote:
> > That seems like something we should add in a future version, if it 
> > really is needed. Baby steps, keep things simple, etc.
> 
> Given the lack of extensibility and negotiation, how would it be added 
> in the future without breaking backwards compatibility?

There's no lack of extensibility and negotiation, both are built into the 
protocol. Future versions of the protocol can simply define new option 
fields that the client can include to announce support and that the server 
can include to announce opt-in. For example, the client could say:

   Sec-WebSocket-Compression: gzip bzip2

...and the server might then respond with:

   Sec-WebSocket-Compression: gzip

...indicating that the client and server will both compress frames using 
gzip. Pretty much anything can be defined; if both the client and the 
server opt in to a feature, nothing constrains what the protocol has to 
look like from then on. We could define an option that, once selected by 
both parties, switches the protocol to an entirely different framing 
mechanism, if we find that the simple framing currently in the spec isn't 
good enough. So long as we define all the interactions of the options, 
we're pretty much open to doing anything in future versions short of 
changing the basic shape of the handshake.

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 22 Jul 2010 08:51:28 +1000

On 22 July 2010 08:28, Ian Hickson <[email-masked]> wrote:

>   Sec-WebSocket-Compression: gzip
Ian,

That will not work, because old versions of websocket are constrained by the
current standard to reject connections with unknown headers.     So if a
future version introduced such a header, it would immediately make new
client unable to interoperate with old servers.

If we do not allow arbitrary headers, then we will severely limit our
options for upgrading the protocol in the future.

---

From: Jamie Lokier <[email-masked]>
Date: Thu, 22 Jul 2010 00:23:28 +0100

Greg Wilkins wrote:
> 
>    On 22 July 2010 08:28, Ian Hickson <[1][email-masked]> wrote:
> 
>      Â  Sec-WebSocket-Compression: gzip bzip2
>      Â  Sec-WebSocket-Compression: gzip
> 
>    Ian,
>    That will not work, because old versions of websocket are constrained
>    by the current standard to reject connections with unknown
>    headers.  So if a future version introduced such a header, it
>    would immediately make new client unable to interoperate with old
>    servers.

Ian, +1 to What Greg said.  It sounds like maybe the current spec
doesn't behave as you intended?

The handshake must permit future clients to interop with the first
widely deployed websocket servers (whatever version of the standard).
That's why "wiggle room" for negotation has to be clearly present in
the first version that gets significant deployment.

It doesn't have to be completely arbitrary headers; it just needs to
be *something* that all compliant servers ignore and future servers
can recognise.

-- Jamie

---

From: "Simon Pieters" <[email-masked]>
Date: Thu, 22 Jul 2010 12:25:52 +0200

On Thu, 22 Jul 2010 00:51:28 +0200, Greg Wilkins <[email-masked]> wrote:

> current standard to reject connections with unknown headers.

No, it doesn't. It says in the Reading the client's opening handshake  
section:

[[
Other fields
    Other fields can be used, such as "Cookie", for authentication purposes.
    Their semantics are equivalent to the semantics of the HTTP headers with
    the same names.

Unrecognized fields can be safely ignored, and are probably either the  
result of intermediaries injecting fields unrelated to the operation of  
the WebSocket protocol, or clients that support future versions of the  
protocol offering options that the server doesn't support.
]]

> So if a

-- 
Simon Pieters
Opera Software

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 22 Jul 2010 21:59:48 +1000

On 22 July 2010 20:25, Simon Pieters <[email-masked]> wrote:

[[
Other fields

Unrecognized fields can be safely ignored, and are probably either the
result of intermediaries injecting fields unrelated to the operation of the
WebSocket protocol, or clients that support future versions of the protocol
offering options that the server doesn't support.
]]

Simon,

I wish it were as you say, and I think there are several sections of the
specification which do indeed suggest that arbitrary headers are possible.

But just yesterday, Ian responded to my post as follows:

Ian hickson wrote:
> On Sat, 8 May 2010, Greg Wilkins wrote:
>>
>> the 76 pre draft actually exclude header other than those mentioned with
>> phrase:
>>
>>   The only options available in this version are the ...
>>
>> While I don't think this text is very clear, I did ask the editor if it
>> was meant to exclude headers not mentioned and he indicated that this
>> was the case.
>
>The text above is non-normative, but the requirements are pretty explicit
> and do indeed not include any provision for including other fields.

So the intent of the editor is clear - arbitrary headers are not meant to be
supported. It is also apparent that at least some implementations do indeed
enforce a prohibition on arbitrary headers and I have already been forced to
modify some servlet filters to prevent them adding some headers.

cheers

---

From: "Simon Pieters" <[email-masked]>
Date: Thu, 22 Jul 2010 14:35:49 +0200

On Thu, 22 Jul 2010 13:59:48 +0200, Greg Wilkins <[email-masked]> wrote:

> the

Good; I believe it is just as I said, since I can't find anything in the  
spec that requires servers to reject connections with unknown headers.  
Instead it says unknown headers can be safely ignored.

> supported.

AFAICT, Hixie was saying that the spec does not allow clients to include  
arbitrary headers (which matches my understanding of the spec). It doesn't  
follow that servers are required to close the connection if they see  
unknown headers.

> It is also apparent that at least some implementations do indeed

Although the spec allows servers to close the connection at any time for  
any reason as they see fit, I would consider it a bug in the server if it  
closes the connection for unknown headers, since as you say it's  
incompatible with future additions to the protocol.

-- 
Simon Pieters
Opera Software