Subject: [hybi] draft-abarth-websocket-handshake-01

From: Adam Barth <[email-masked]>
Date: Sat, 6 Nov 2010 00:44:40 -0700

Thanks for all your valuable feedback on the CONNECT-based handshake.
I've incorporated your feedback into an updated version of the
handshake.  (Note, uploading new Internet-Drafts is current disabled
because of the meeting in Beijing, so I've hosted it on my web site
for the time being.)

http://www.adambarth.com/experimental/websocket.txt

Notable changes:

1) I've moved the metadata in the client's initial message from being
an entity-body of a CONNECT request to being an HTTP header.  The
handshake should now comply with the HTTP requirements on CONNECT
requests.
2) I've removed the dependency on AES-128-CTR.  The handshake now uses
a simple XOR-based masking scheme.  I kept the dependency on SHA1,
however.  SHA1 is incredibly widely implemented that I don't think
this is a problem.
3) I've switched to using JSON to encode the handshake metadata.  Some
folks pointed out that they'd be unable to re-use their HTTP header
parsing code for parsing the handshake metadata, so JSON seemed like
the most likely thing for servers to get right.

Notable non-changes:

A) I've left the hostname used in the CONNECT request as an invalid
host name.  I can see an argument for replacing this with the
attacker-supplied host name, but I'd really prefer to keep all
attacker-chosen bytes out of the initial handshake.

Thanks,
Adam

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 6 Nov 2010 09:23:33 +0100

> attacker-chosen bytes out of the initial handshake.

So basically all the concerns raised about routing information being
unusable by existing HTTP infrastructure were simply wiped out :-(

Thanks,
Willy

---

From: Adam Barth <[email-masked]>
Date: Sat, 6 Nov 2010 01:48:45 -0700

> unusable by existing HTTP infrastructure were simply wiped out :-(

There are tradeoffs in designing protocols.  In the absence of hard
evidence either way, this is a bit of a judgment call.  Honestly, I
consider making the routing information unusable by existing HTTP
infrastructure a feature.  Some of most problematic vulnerabilities
with the old protocol involve confusing existing HTTP infrastructure
to route WebSocket messages incorrectly.

Adam

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 6 Nov 2010 10:50:22 +0100

On Sat, Nov 06, 2010 at 01:48:45AM -0700, Adam Barth wrote:
> infrastructure a feature.

If the protocol ever gets adopted in this state, I wish this sentence
remains on the net so that hosting providers will have a quick explanation
for their customers when they ask why they can't have WebSocket !

> Some of most problematic vulnerabilities

Well, the presence of host headers, cookies or whatever has not been
demonstrated as a vulnerability at all. There were just some suppositions
that maybe some dirty implementers might use strstr() to parse some
headers.

Also, your valid concerns about the risks of having the tunnelled data
being interpreted by some intermediaries as a second request were clearly
addressed by several proposals, including Greg's suggestion of switching
some bits, mine of prefixing the tunnelled data with a small sequence of
"special" bytes (eg: \x00 \xFF \x00 \xFF), or even my Mark's suggestion
of using another port by default.

So I don't understand why you insist in pushing your proposal that strong
since it has some important issues that are only justified as the way to
protect against some situations for which other solutions exist.

Willy

---

From: Scott Ferguson <[email-masked]>
Date: Sat, 06 Nov 2010 12:36:45 -0700

> to route WebSocket messages incorrectly.

So don't use the HTTP port.

If you're opposed to using the HTTP infrastructure, don't use the HTTP port.

It's not the purpose of HTTP to be a tunneling mechanism for new 
protocols to bypass firewalls.

-- Scott

> Adam
> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi
>
>
>
>

---

From: Brodie Thiesfield <[email-masked]>
Date: Sun, 7 Nov 2010 22:05:48 +0900

Re: JSON

What is the problem space that needs to be solved by using JSON?

Parsing of HTTP headers are simple. That is the beauty of them. They
do not need any sort of library do do so. The "reuse" of HTTP
components is practically unimportant. Ignoring things like header
continuations (which many implementations already do), parsing at the
most simple level consists of searching for a colon, whitespace and
CRLF in order to get key and value pair.

JSON however is not a simple parsing problem. There are multiple data
types and balanced braces that need to parsed. It requires more effort
to implement for no visible benefit. In contrast, rather than "likely
to get right", it seems that it is far more likely that parsing
problems will exist in the JSON headers and result in servers or
clients not correctly interpreting the messages as they should.

You have been worried about servers not correctly implementing parsing
of HTTP requests which basically only requires them to watch CRLF
pairs, and instead propose that servers need to do JSON parsing which
is far more complex. This change to your proposal makes no sense and
was done with almost no discusssion.

Regards,
Brodie

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 8 Nov 2010 13:56:24 +1100

> If you're opposed to using the HTTP infrastructure, don't use the HTTP port.

+1

> It's not the purpose of HTTP to be a tunneling mechanism for new protocols
> to bypass firewalls.

... except that Upgrade and CONNECT are both HTTP sanctioned
mechanisms to tunnel through firewalls.

So  instead I'd say that if you want to use HTTP to tunnel through
firewalls, then use the HTTP mechanisms to tunnel through firewalls.
If you think there are problems with these mechanisms, then raise
those problems with HTTPbis.

cheers

---

From: Maciej Stachowiak <[email-masked]>
Date: Sun, 07 Nov 2010 20:52:01 -0800

Why does the proposal use such mysterious and unmemorable values for the fixed strings used in various places? Examples:

Invalid CONNECT hostname -> 1C1BCE63-1DF8-455C-8235-08C2646A4F21.invalid
handshake-mask seed string -> C1BA787A-0556-49F3-B6AE-32E5376F992B
acceptance-proof seed string -> 258EAFA5-E914-47DA-95CA-C5AB0DC85B11
client-to-server mask seed string -> 363A6078-74D2-4C0B-8CBC-1E6A36E83442
server-to-client mask seed string -> 2306C3BE-0ACF-42C0-B69E-DFFE02CFA346

Is there a reason these need to be strangely formatted hex numbers instead of something like "WebSocket.invalid"? Is there a reason for them all to be different?

This isn't a huge deal but it would be somewhat nicer if there didn't have to be 5 lengthy mystery constants in a protocol implementation.

Regards,
Maciej

---

From: Willy Tarreau <[email-masked]>
Date: Mon, 8 Nov 2010 07:17:53 +0100

> This isn't a huge deal but it would be somewhat nicer if there didn't have to be 5 lengthy mystery constants in a protocol implementation.

Those probably are very good random numbers generated from a high quality
source, that give a better feeling of security.

Willy

---

From: Willy Tarreau <[email-masked]>
Date: Mon, 8 Nov 2010 07:18:42 +0100

+1

Willy

---

From: Wenbo Zhu <[email-masked]>
Date: Tue, 9 Nov 2010 10:32:26 +0800

> CRLF in order to get key and value pair.
If there is actually rich structure-typed meta data, then JSON would make
sense, or something else other than the simple key-value format.
On the other hand, non-browser clients may use WebSocket as well ... or is
this ever the goal?

- Wenbo

---

From: Brodie Thiesfield <[email-masked]>
Date: Tue, 9 Nov 2010 13:28:13 +0900

On Tue, Nov 9, 2010 at 11:32 AM, Wenbo Zhu <[email-masked]> wrote:
> On Sun, Nov 7, 2010 at 9:05 PM, Brodie Thiesfield <[email-masked]>
>> Re: JSON
>>

Representation of structured data is the great advantage of JSON.
However, I believe that it is more desirable for the base protocol to
be simple to parse. This reduces the likelihood of parsing errors
leading to insecurities. It also makes the protocol easier to
implement.

WebSocket will not be used only in the browser <-> webserver market,
although this is obviously the primary focus of this group. It has the
capability to be used as a fairly simple low overhead general purpose
async bidirectional protocol. This would make it suitable for many
different uses, and having browsers able to speak it natively makes it
even more attractive.

If easy to implement, then I expect that it will go on to be used for
many different purposes. Therefore keeping the implementation
requirements low is a good thing.

Regards,
Brodie

---

From: Zhong Yu <[email-masked]>
Date: Mon, 8 Nov 2010 23:11:02 -0600

JSON: my guess is that Adam needs a way to pack multiple key-value
pairs into one string (as a HTTP header value). There's no point to
spend too much time on the detail of that, so he just picked a popular
one for now.

I think we can transmit these data in a WS frame after the HTTP head.
The HTTP part can be really simple, containing UPGRADE/CONNECT, maybe
a HOST, or other things that must reside in a HTTP head. Everything
else can be placed in the following WS frame.

In that case, we probably want to define a standard key-value storage
format in WS frames, which could be useful for other control frames,
or even for applications.

- Zhong

---

From: Adam Barth <[email-masked]>
Date: Tue, 9 Nov 2010 10:31:17 -0800

> Is there a reason these need to be strangely formatted hex numbers instead of something like "WebSocket.invalid"? Is there a reason for them all to be different?

They're just UUIDs generated using uuidgen.  The property we need from
these values is that no one else is using them for another purpose.
We could approximate that by using a string containing "websocket."
All the seed strings need to be different to ensure we're getting
distinct hash values.

Of these, the hostname one is the least important to be unique.  We
could certainly change that one to WebSocket.invalid if you think
that's more aesthetic.  The acceptance-proof seed is the most
important to be unique.

> This isn't a huge deal but it would be somewhat nicer if there didn't have to be 5 lengthy mystery constants in a protocol implementation.

Using UUIDs is probably overkill to guarantee uniqueness, but I didn't
see much cost in using them.

Adam

---

From: Adam Barth <[email-masked]>
Date: Tue, 9 Nov 2010 10:42:16 -0800

This is now posted officially:

http://www.ietf.org/id/draft-abarth-websocket-handshake-01.txt

This is the same as the draft I linked to earlier, with one change:
I've changed the crazy CONNECT host name to "websocket.invalid"
instead of the UUID-based host name.

Adam

---

From: "Alexander Philippou" <[email-masked]>
Date: Thu, 11 Nov 2010 17:49:29 +0200

Adam,

Requiring the presence of a JSON library just in order to parse WS headers is an overkill.

While browser clients do have easy access to JSON serialization, the same does not necessarily apply to non-browser clients (servers too). For example JSON was introduced to .NET in v3.0 (at least AFAIR). Earlier .NET or .NET CF versions do not have out-of-the-box access to JSON.

Also, JSON might be superseded by another technology in a few years. WS might be here for many more years after JSON fades away. It's unwise to ask future implementers to support a legacy library just for header parsing.

Implementing a custom parser for the header is easy, this is a common part of a protocol implementer's work. I would even say that a binary encoded header makes more sense than JSON. The protocol already requires the handling of integer length fields and frame decoding. Implements will anyway have to deal with binary encoding of the data, so why not implement a binary header such as [length][field_name][length][field_data] that would be able to carry any type of data along with utf-8 strings.

Alexander

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On
> Behalf Of Adam Barth
> Sent: Tuesday 9 November 2010 20:42
> To: Maciej Stachowiak
> Cc: Hybi
> Subject: Re: [hybi] draft-abarth-websocket-handshake-01
> 
> >> Why does the proposal use such mysterious and unmemorable
> values for the fixed strings used in various places? Examples:
> >>
> >> Is there a reason these need to be strangely formatted hex
> numbers instead of something like "WebSocket.invalid"? Is there a
> reason for them all to be different?
> >
> >> This isn't a huge deal but it would be somewhat nicer if there
> didn't have to be 5 lengthy mystery constants in a protocol
> implementation.
> >