Re: #250 / #251 (connect bodies)

On 28/10/2010, at 5:33 PM, Adam Barth wrote:
>   REQ. 7:  The WebSocket protocol MUST allow HTTP and WebSocket
>      connections to be served from the same port.

Presence in a requirements document doesn't guarantee that any given feature will get through. Considering the hoops you're having to jump through to meet this requirement (does the reqs document have consensus, by the way?), it's a wonder it's still considered relevant.

In other words, who actually *wants* this?

>> What property are you looking for out of using the CONNECT method to the server that rules out other methods?
>> What specific security vulnerabilities are raised by using Upgrade (a useful discussion to be had in any case)?
> There are a lot more details in
> <>,


> From CONNECT, specifically, we'd like to get WebSocket-oblivious
> intermediaries to ignore the rest of the bytes on the socket.  CONNECT
> lets them know that the rest of the bytes coming from the client
> aren't going to be HTTP, so they shouldn't try to understand the
> semantics of those bytes.

Explicitly configured forward proxies -- as opposed to "reverse" proxies, interception (a.k.a. "transparent") proxies, L7 load balancers, firewalls and the like -- will indeed do this. Whether any of the rest will is anyone's guess, and depends upon how they're coded, whether they're ever used as a forward proxy, and how generous / clued-up the administrator is. 

> If everyone perfectly implemented HTTP-as-specified, we could use
> Upgrade for that purpose because that's what Upgrade is supposed to
> mean also.  Unfortunately, Upgrade is extremely rare in
> HTTP-as-she-be-spoke, which means many of these intermediaries think
> that the subsequent bytes sent by the client have HTTP semantics.

How does that follow?

Upgrade is an optional mechanism. The client requests upgrade, and the server decides whether or not it's upgrading the protocol; if it does, it uses a 101 Switching Protocols response.

That, however, is predicated upon the presence of the Upgrade header in the request. Upgrade is hop-by-hop, which means that it'll be removed by well-behaved intermediaries, unless they understand the protocol being upgraded to. 

For the remainder (i.e., the not-well-behaved intermediaries), in my testing setting the appropriate Connection: header catches pretty much all of them.


POST /foo HTTP/1.1
Upgrade: WebSockets/5.0
Connection: Upgrade

will catch almost every deployment (certainly more than could be characterised as "extremely rare").  The ones that aren't can be worked around, because they're only deployed server-side (e.g., Pound, nginx).

>  Of
> course, in WebSockets, the attacker is given great latitude to select
> bytes-on-the-wire after the handshake completes, which means the
> attacker's script running in a browser can craft bytes that look a lot
> like HTTP but avoid the security invariants the browser usually
> imposes on script code running on behalf of a web site.

You're missing the point here -- a box that isn't expecting and explicitly handling CONNECT will also think that HTTP semantics apply beyond the end of the message. 

> Most notably, the attacker can spoof the Host header.  If you consider
> an enterprise deployment with a firewall and a transparent (Roy will
> correct me that the proxy isn't technically transparent, but that's
> folks call it)

Correct term is 'interception proxy'.

> proxy (which is a common deployment pattern), the
> attacker can sometimes get the transparent proxy to retrieve HTTP
> resource otherwise protected by the firewall.  For example, stealing
> product plans from an internal wiki.

If you're looking to prevent that type of attack, CONNECT isn't going to be sufficient. See discussion re: using another port.


Mark Nottingham

Received on Thursday, 28 October 2010 07:07:08 UTC