Re: [hybi] Extensibility mechanisms?

Willy Tarreau <w@1wt.eu> Thu, 22 July 2010 22:16 UTC

Return-Path: <w@1wt.eu>
X-Original-To: hybi@core3.amsl.com
Delivered-To: hybi@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 48B7F3A6A15 for <hybi@core3.amsl.com>; Thu, 22 Jul 2010 15:16:33 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.467
X-Spam-Level:
X-Spam-Status: No, score=-2.467 tagged_above=-999 required=5 tests=[AWL=-1.424, BAYES_00=-2.599, HELO_IS_SMALL6=0.556, J_BACKHAIR_24=1]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Pgx-HXcc+N9O for <hybi@core3.amsl.com>; Thu, 22 Jul 2010 15:16:32 -0700 (PDT)
Received: from 1wt.eu (1wt.eu [62.212.114.60]) by core3.amsl.com (Postfix) with ESMTP id 9BD643A6A34 for <hybi@ietf.org>; Thu, 22 Jul 2010 15:16:30 -0700 (PDT)
Received: (from willy@localhost) by mail.home.local (8.14.4/8.14.4/Submit) id o6MMGiWL017880; Fri, 23 Jul 2010 00:16:44 +0200
Date: Fri, 23 Jul 2010 00:16:44 +0200
From: Willy Tarreau <w@1wt.eu>
To: Maciej Stachowiak <mjs@apple.com>
Message-ID: <20100722221644.GD16808@1wt.eu>
References: <4C479130.4020500@caucho.com> <AANLkTikLDjBP-Xs5t6TxmJuq4nG8jwThQ=n34B4cEmup@mail.gmail.com> <4C479CE4.6070805@caucho.com> <AANLkTims1er0Rbv0ysP4gRs1Kd0He8hapHeJ3nON=JQa@mail.gmail.com> <4C47C5B0.3030006@caucho.com> <AANLkTi=ND-FOH8OoD=TCbiyeSZ-h0LhxQBXN5w-2hfvj@mail.gmail.com> <20100722055452.GL7174@1wt.eu> <F412C956-038F-400D-A431-C42B4C7B829C@apple.com> <20100722140726.GD12582@1wt.eu> <F20E03DF-16F3-4A7E-869D-D25AD05301AB@apple.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
In-Reply-To: <F20E03DF-16F3-4A7E-869D-D25AD05301AB@apple.com>
User-Agent: Mutt/1.4.2.3i
Cc: Hybi <hybi@ietf.org>
Subject: Re: [hybi] Extensibility mechanisms?
X-BeenThere: hybi@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: Server-Initiated HTTP <hybi.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/hybi>
List-Post: <mailto:hybi@ietf.org>
List-Help: <mailto:hybi-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 22 Jul 2010 22:16:33 -0000

Hi Maciej,

On Thu, Jul 22, 2010 at 10:05:44AM -0700, Maciej Stachowiak wrote:
> > Maybe I'm mistaken, but why couldn't such JS code simply make use of the
> > browser's HTTP client to do so ? Posting a form, reloading an image from
> > a given URL or making an XMLHttpRequest seems perfectly possible right now,
> > so trying to do that via the WebSocket code would bring nothing at all.
> 
> All of the mechanisms you listed have significant restrictions:
> 
> 1) Reloading an image from a given URL, the in-browser attacker cannot use any method other than GET or set any custom headers beyond what the UA sends normally. And the attacker definitely cannot read back the reply.

Right.

> 2) Posting a form, the in-browser attacker cannot use any method other than GET or POST, set any custom headers beyond what the UA sends normally, or send content in anything but a short list of existing formats. And the attacker definitely cannot read back the reply.

OK.

> 3) Using cross-site XMLHttpRequest, the attacker cannot use any method other than GET or POST, set any custom headers, or include a message body in anything but a small set of formats, unless the target site explicitly opts in via an OPTIONS request (cross-site XHR is specifically designed to only be able to do things you can do with form submission).

I was not aware that OPTIONS was possible there.

> Even given all that, many sites do in fact have vulnerabilities to cross-site form posting. This class of attacks is called Cross-Site Request Forgery, or CSRF. Typically, these are attacks on integrity, not confidentiality, since the attacker cannot read the reply. WebSocket creates the possibility of extending the attack surface for these kinds of attacks, and for the possibility of attacks on confidentiality as well as integrity.

Yes I know them too and have experimented with that about 10 years ago, at times
I think there was no name for this practice. It was fun to put some IMG SRC links
on pages referencing printer_ip:9100 and see the face of people observing their
printers dump pages of HTTP requests when they just loaded the page ;-)

> > The same is true here : why would the JS code try to use the normal HTTP
> > client if the browser supports WebSocket, with which the code would be
> > able to have finer control over its attack ?
> 
> Because WebSocket would require a successful handshake before sending any actual messages, while an HTTP POST with XHR would blindly send the post body without validating the handshake. If the server doesn't thoroughly verify the client part of the handshake, then it may be tricked into processing  a POST body that looks like a series of WebSocket messages. If it authenticates with a cookie, then this could be used to inject control messages with a side effect, depending on the nature of the WebSocket service.

OK I understand your example now, which is particularly interesting
because it's very close to the initial issue of passing some requests
in the extra bytes of the handshake.

So it seems to me that what makes WS<->HTTP cross-protocol attacks possible
is just the fact that we're using one of the GET, POST, OPTIONS method that
can be controlled from the JS running on the browser.

A few weeks ago I asked why we wouldn't use the CONNECT method in the handshake,
in conjunction with the 200 Established response. There were some objections
that this would either possibly be incompatible with some existing servers
or may cause some havoc on some reverse-proxies that also happen to support
proxy commands.

But after thinking about it, any method can be used with an Upgrade request,
what's important is that we get the 101 in response. Even a new dedicated
method would do it fine and definitely put an end to any such WS<->HTTP
confusion. Would it be something that we could dream of to have, say, a
new "UPGRADE" or "SWITCH" method that could be used only with an Upgrade:
header and Connection: upgrade in order to get a 101 Switching protocols
response ?

We could then have something like this :

        SWITCH /demo HTTP/1.1
        Host: example.com
        Connection: Upgrade
        Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
        Sec-WebSocket-Protocol: sample
        Upgrade: WebSocket
        Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
        Origin: http://example.com

        ^n:ds[4U

We could state that this method would not allow 2xx responses, only
only 101, 3xx, 4xx or 5xx would be allowed.


> >>> If this is indeed the issue you're talking about, then I don't see why
> >>> the HTTP-based handshake could be a problem there. It's not more than
> >>> any other common HTTP request, it's even better in that no data should
> >>> flow until the server has correctly replied indicating proper support
> >>> for the protocol.
> >> 
> >> What's "the HTTP-based handshake"?
> > 
> > I mean the HTTP Upgrade mechanism.
> 
> Do you mean the specific mechanism currently in <http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76> or something else?

Yes/no, sorry for the confusion, I was meaning the *standard* HTTP upgrade
mechanism which makes use of Upgrade: <proto> + HTTP/1.1 101 Switch proto.
RFC2817 defines it in more details than RFC2616. This is what WS tries to
use, but since there's this absurd ambiguity whether it's HTTP or not, I'd
prefer to talk about the real spec.

> > I agree with the *extremely subtle* point. But that's also why I'd rather
> > not try to reinvent within a small group things that are already efficient
> > and not proven wrong. We must accept that a small group is never smarter
> > than those outside the group and that a few hours designs have little
> > chance of being more robust than those which have survived exposure to the
> > world for 10 years or so.
> > 
> > It's just like when you see developers implement their own crypto algorithm
> > because "the public ones have not been broken yet but they're attacked, so
> > let's be safe and write a new one". The ones I have talked about on this
> > subject were really convinced their work was better than everything else,
> > while it was a disaster. That's what I'd prefer we avoid here.
> > 
> > However, enforcing a strict mode of operations based on something which
> > already works, or as Sal suggested, enforcing a stricter standard is the
> > right way to go.
> 
> I don't think anyone has previously invented a solution to this problem, so we don't have the option of using a well-vetted 10-year-old design. I also do not think passing off responsibility to another group increases our odds of creating a secure protocol.

In fact I was talking about the HTTP Upgrade which is defined since
RFC2068 (01/1997) and which WebSocket tries to use. While it's not
much used, at least it's not a new design.

> > We should spend some time trying to enumerate what aspect(s) of the HTTP-based
> > handshake we believe may be a problem regardless of the protocol deployed on
> > the target server.
> 
> I think it would be worth enumerating the pros and cons of the TLS-based approach and recording them somewhere (such as on a wiki page).

That's a good idea, and we could also do that for other suggestions
that come back from time to time (eg: adding this or that HTTP header,
or using this or that method). I have no idea where this can be put
though.

Regards,
Willy