Re: [hybi] Handshake was: The WebSocket protocol issues.

Greg Wilkins <gregw@webtide.com> Thu, 30 September 2010 05:09 UTC

Return-Path: <gregw@webtide.com>
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 113AB3A6D86 for <hybi@core3.amsl.com>; Wed, 29 Sep 2010 22:09:37 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.744
X-Spam-Level:
X-Spam-Status: No, score=-1.744 tagged_above=-999 required=5 tests=[AWL=0.233, BAYES_00=-2.599, FM_FORGED_GMAIL=0.622]
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 LzpqFGcif+PM for <hybi@core3.amsl.com>; Wed, 29 Sep 2010 22:09:33 -0700 (PDT)
Received: from mail-iw0-f172.google.com (mail-iw0-f172.google.com [209.85.214.172]) by core3.amsl.com (Postfix) with ESMTP id 7F70E3A6D4D for <hybi@ietf.org>; Wed, 29 Sep 2010 22:09:29 -0700 (PDT)
Received: by iwn3 with SMTP id 3so2357567iwn.31 for <hybi@ietf.org>; Wed, 29 Sep 2010 22:09:03 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.231.182.5 with SMTP id ca5mr3051229ibb.68.1285823343226; Wed, 29 Sep 2010 22:09:03 -0700 (PDT)
Received: by 10.231.39.199 with HTTP; Wed, 29 Sep 2010 22:09:03 -0700 (PDT)
In-Reply-To: <8E29D153-792A-4401-820C-14B654385FB6@apple.com>
References: <AANLkTikszM0pVE-0dpZ2kv=i=y5yzS2ekeyZxtz9N=fQ@mail.gmail.com> <62B5CCE3-79AF-4F60-B3A0-5937C9D291D7@apple.com> <AANLkTikKc+4q_Q1+9uDo=ZpFF6S49i6vj2agZOGWVqKm@mail.gmail.com> <E2D38FF3-F1B9-4305-A7FC-A9690D2AEB4A@apple.com> <AANLkTikRYB_suPmSdH3uzGmdynozECRszDx+BpUvtZ4h@mail.gmail.com> <5CBF797D-A58E-4129-96B3-164F6E7409B9@apple.com> <4CA0D0D2.4040006@caucho.com> <AANLkTinACqm-GxUPhvFMf6_sGfeJofwy1r=28o=vgM43@mail.gmail.com> <4CA12810.8020006@caucho.com> <AANLkTimrMfXrnVMjU3f57L_sO7usyYQ56rBM4aMb2Pfr@mail.gmail.com> <20100928052501.GD12373@1wt.eu> <CA8029B0-71A3-44ED-88C6-934FE833BBA2@apple.com> <AANLkTim+fXj-h6OS3OdcfVfh3Q1UwxD8NLVawb=AWHX+@mail.gmail.com> <4FAC5C93-9BDF-4752-AFBC-162D718397AB@apple.com> <AANLkTikcH1W3bQwumqHbe-Yqa3XdoJqCa2b-mZuvoQ7g@mail.gmail.com> <9746E847-DC8B-45A7-ADF3-2ADB9DA7F82E@apple.com> <AANLkTik9igUwoxVrktoBoZrPoUW=Tjh7HyVbGJgQYes-@mail.gmail.com> <9F595226-FA0A-4C38-A6D0-0F4214BD7D21@apple.com> <AANLkTi=ieqL=mGW3POW7g0QEs4XWYT=zq_BKiWb2BxtK@mail.gmail.com> <8E29D153-792A-4401-820C-14B654385FB6@apple.com>
Date: Thu, 30 Sep 2010 15:09:03 +1000
Message-ID: <AANLkTim1-h=aEskXM7WdRhUX7WaOXKpHamWHuPZ_JSTt@mail.gmail.com>
From: Greg Wilkins <gregw@webtide.com>
To: Maciej Stachowiak <mjs@apple.com>
Content-Type: text/plain; charset="UTF-8"
Cc: hybi <hybi@ietf.org>
Subject: Re: [hybi] Handshake was: The WebSocket protocol issues.
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, 30 Sep 2010 05:09:37 -0000

On 30 September 2010 11:52, Maciej Stachowiak <mjs@apple.com> wrote:

> The injection we are talking about is client side, not server side. All browser-hosted HTTP and WebSocket APIs let you provide a URL, but will not send a request line that contains whitespace.


So you are concerned about the ultra simple WS server that "parses"
the HTTP header with regex's like

  Sec-WebSocket-Key1:([A-Fa-f0-9]*)
  Sec-WebSocket-Key2:([A-Fa-f0-9]*)


Well such a simple server is not going to care if those fake fields
are in the request line or not, and will equally be fooled by XHR
headers like:

   Evil-Genius-1:  Sec-WebSocket-Key1:a34 89j 9a 9fjadsa91df
   Evil-Genius-2:  Sec-WebSocket-Key2:a423s 4  89j 5559aadsa91df
   Evil-Genius-3:  Connection:Upgrade

that will match regexes like

  Sec-WebSocket-Key1:([ A-Aa-z0-9]*)

While HTTP requests can be sent without XHR, these are of no value as
you will see in the analysis below that the method name must be
vulnerable and that will need XHR rather than a src element.

Note also that we are now requiring HTTP compliance before the 101, so
we can test for servers that do not do basic HTTP format checking (
eg by trying requests without any CRLF).

But even if such a server did escape into the wild, I think our
defence in depth will still deal adequately with this threat.

If the request sent had a URL like:

  /some/path/Sec-WebSocket-Key1:0123456789ABCDEF:Sec-WebSocket-Key2:0123456789ABCDEF:Upgrade:WebSocket:

or the headers above, then the regex's could indeed extract the
"injected" keys instead of the ones included in the header, and see
and upgrade header.

Let's also assume that this server has also ignored the URL, because
otherwise the injected URL would be gibberish to it and it would not
initiate a websocket.

Let's further assume that the rest of the request has been read and discarded.

The WS server will now send a 101 response followed by a ping message
with the the hash of the wrong keys in it, and a server-nonce.

The client will receive the 101 - and I'm not entirely sure what a
browser will do with it.   I would not be surprised if it treated it
as an error, but let's assume that the browser doesn't and continues
to use that connection.

The ping message is now sitting in the connection waiting for the
browser to read and process it.  Some browsers will error at this
stage because of the unsolicited input on the connection.  But let's
assume that they don't and they just leave the ping unread for now.

The server is waiting for a pong message before it concludes the
connection is OK.

The client must now somehow send that pong message on the wire.  I do
not believe that a valid pong message can be formed by a HTTP browser,
as the method would need to be formed from control characters.   But
let's assume that it is a broken browser as well and that some how it
allows a correctly formed pong message to be sent.   However, it
cannot form the pong message, because it does not know what the server
nonce is - thus it is not able to complete the handshake and without
the pong, the server will never process any messages that the client
might send.

But let us assume that the poor WS server has a bad RNG and the server
nonce was predictable (or even fixed), then maybe this broken client
could be tricked to send a pong with the right contents.

So with all these assumptions, we have now managed to establish a WS
connection from a HTTP client.  But this is what we want to enable
anyway - for browsers to be able to do this with the websocket API.
However the HTTP client might be able to send a very contrived packet
with the RSV bits and opcode set, but with the content of the frame
being made up of HTTP headers.   So the WS server must have to take
some undesirable action based on the RSV bits and op codes - but this
is a simple WS server, so that is highly unlikely.

Meanwhile, the server might have been sending data packets in
anticipation of the pong.  So let's say the browser sends a request
anyway, even though it is not a pong and will break the connection.
The browser will now look to the connection to read the response and
will see the waiting ping.   This does not look like a HTTP response,
so the browser will throw and error.  It will never process the server
messages after the ping and will certainly not make them available to
the javascript application in any way.

So to recap, this threat is based on:
 + WS server that ignores the URL
 + WS server that does not parse the HTTP and specifically does not
look for any CRLF
 + The browser does not error on the 101 response
 + The browser does not error on the unsolicited ping data
 + The browser allows a method name to be made with control characters
so that a PONG packet can be sent.
 + WS server has a predictable RNG
 + The WS server will take some undesirable action based on the
op-codes and RSV bits
 + The WS server will need to ignore the HTTP headers sent as the
content of any such forged frame.

Adding the space encoded keys does not help because XHR headers can be
used as indicated above.

I think this analysis just proves how insisting on HTTP compliance is
actually good for security as we can test to make sure that WS servers
are parsing CRLF.   It also shows that the space injection gives no
protection real protection and is only perceived to be more secure.
It also indicates that a server nonce is useful in increasing the
depth of defence.


regards