Subject: [hybi] handshaking with CONNECT

From: Patrick McManus <[email-masked]>
Date: Tue, 12 Oct 2010 14:54:35 -0400

Hi All,

First - Adam, Eric, thank you for your detailed CONNECT based handshake
proposal. It made me think about a number of issues in a different
light.

As others have said, we seem to have 3 competing approaches: Upgrade,
CONNECT, and TLS/NPN.

Based on the work this group has done and my role with Mozilla Firefox,
I support something based on the CONNECT proposal from Eric and Adam. I
think this contribution is a good example of the value the IETF working
group process can add to the design of the WebSockets protocol. Some of
the attacks it prevents are theoretical but they are not outlandish to
conceive of, and it does so at a very reasonable cost. The basic form of
your proposal is a practical thing to engineer and deploy and the best
option we've seen imo.

The discussion of Upgrade in the face of a transparent proxy that will
just forward it was particularly sobering with respect to the subsequent
data on the wire. I understand a fully compliant implementation will be
safe in that scenario but I think it is prudent to be conservative with
respect to the handling of connection, upgrade, and close in a request
header - those things have all been phased in over time and http has a
strong tradition of "I dont recognize it so I forward it" that would be
disastrous here. The shared hosting scenario is a little more contrived,
but I also agree it is worth taking seriously.

As a minor point, I would agree with the earlier on list suggestion that
the AES-128 tunnel be replaced with a more simple XOR using a 32 bit key
exchanged in the same way as the AES key was proposed to be sent. As you
say, the goal here is not encryption but rather preventing the attacker
from placing particular byte sequences directly in the stream. XOR will
accomplish that at significantly less complexity than AES. (I'm not
saying AES is severely complicated but I guess I am asking whether
anything is gained in this case by the complexity, cache pollution,
etc.. it adds over xor.).. if you want an encrypted tunnel then use the
TLS version of the protocol.

One final point - at first read I had a very hard time figuring out
whether or not this approach totally busted proxy support. Adam helped
my understanding of that here:

http://www.ietf.org/mail-archive/web/hybi/current/msg04324.html

When you rewrite this as a proposed contribution to the draft-ietf WG
document (and please do that!), some text around the HTTP proxy case
would be very helpful. Indeed the case here is much more compelling than
it is for "Upgrade", which could theoretically work but at initial
deployment would just result in non-traversable connections. So CONNECT
is a big improvement there.

Thanks!
-Patrick

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 12 Oct 2010 21:45:19 +0200

Patrick,

I also share some of your feelings on this handshake, reason why I'd like 
to see some issues addressed.

> TLS version of the protocol.

Also, AES would force larger blocks than necessary for small frames. If we
have to keep that, maybe we should check the framing again to see if it's
possible to simplify its handling at the cost of a few more bytes that will
not change the AES chunking anyway ? For instance, I remember someone who
said he was having issues with the bitmasks. But I'd rather see a XOR here
too, I agree.

> is a big improvement there.

What I also like in using the CONNECT+200 method is that it's exactly what
it was designed for and how it's already used for proxies : establishing
a bidirectional tunnel that will only be terminated on a close. It's the
equivalent of the GET+upgrade but probably with a stricter behaviour on
failure cases.

Regards,
Willy

---

From: Adam Barth <[email-masked]>
Date: Tue, 12 Oct 2010 13:11:10 -0700

> said he was having issues with the bitmasks. But I'd rather see a XOR here

AES-128-CTR is a stream cipher.  There is no block size.  There's zero
impact on the framing.

The way it works is you feed AES-128-CTR a key and it starts
outputting a sequence of pseudo-random bits.  You then take that
stream of bits and XOR it with your data stream and then send that on
the wire.  If you're excited about XOR, AES-128-CTR is your friend.
:)

Adam

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 12 Oct 2010 22:18:16 +0200

> the wire.  If you're excited about XOR, AES-128-CTR is your friend.

Nice, thanks for this clarification Adam !
So that means that for servers it should not be that hard to implement
(assuming availability of an easily portable library). Having a stream
cipher means we could even think of fgetc() and fputc() wrappers that
are able to easily process one char at a time without having to bother
about buffering, only internal state. That sounds adequate for what we're
trying to do !

Willy

---

From: Greg Wilkins <[email-masked]>
Date: Wed, 13 Oct 2010 07:57:40 +1100

Does anybody have any data on how existing intermediaries handle CONNECT?

Are we sure that CONNECT is going to transit networks without being
redirected to the invalid hostname supplied?

---

From: Micheil Smith <[email-masked]>
Date: Wed, 13 Oct 2010 09:05:22 +1100

On 13/10/2010, at 7:18 AM, Willy Tarreau wrote:

> are able to easily process one char at a time

I don't think we should be encouraging the one char at a time processing,
take the example of sending large data over websockets or binary data,
for large data it's going to get incredible slow to parse the packets.

> without having to bother about buffering, only internal state. That sounds
> adequate for what we're trying to do !

– Micheil.

---

From: John Tamplin <[email-masked]>
Date: Tue, 12 Oct 2010 18:26:36 -0400

> redirected to the invalid hostname supplied?

I assume this would be intended for the end server -- if the browser
was configured to use a proxy, it would connect to that proxy as
normal, and once the connection to the remote serve was established
instead of then issuing a GET as usual it would issue the bogus
CONNECT.

It does get a bit tricky when the entity interpreting that CONNECT is
not the end server, but then it would have to deal with Upgrade the
same way.

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

---

From: Willy Tarreau <[email-masked]>
Date: Wed, 13 Oct 2010 05:31:24 +0200

> not the end server, but then it would have to deal with Upgrade the

Well, the minor difference is that the Upgrade would be used in a perfectly
defined way while the CONNECT is a bit tricky here. However, a transparent
intermediary should not use the request to determine next hop's IP address,
but the original target IP address. So in theory, this should still work.

Also, CONNECT has more chances to work than GET+Upgrade through hardware
LBs and such components, since they're already able to load-balance proxy
farms that make use of CONNECT.

Regards,
Willy