Re: [hybi] Frame size

Ian Hickson <ian@hixie.ch> Mon, 19 April 2010 02:40 UTC

Return-Path: <ian@hixie.ch>
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 A0D1F3A6986 for <hybi@core3.amsl.com>; Sun, 18 Apr 2010 19:40:43 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.942
X-Spam-Level:
X-Spam-Status: No, score=-1.942 tagged_above=-999 required=5 tests=[AWL=0.657, BAYES_00=-2.599]
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 37LgYNeLeEzM for <hybi@core3.amsl.com>; Sun, 18 Apr 2010 19:40:42 -0700 (PDT)
Received: from looneymail-a4.g.dreamhost.com (caibbdcaaaaf.dreamhost.com [208.113.200.5]) by core3.amsl.com (Postfix) with ESMTP id A099C3A695E for <hybi@ietf.org>; Sun, 18 Apr 2010 19:40:42 -0700 (PDT)
Received: from ps20323.dreamhostps.com (ps20323.dreamhost.com [69.163.222.251]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by looneymail-a4.g.dreamhost.com (Postfix) with ESMTP id B1E7B8521; Sun, 18 Apr 2010 19:40:20 -0700 (PDT)
Date: Mon, 19 Apr 2010 02:40:19 +0000
From: Ian Hickson <ian@hixie.ch>
To: "Thomson, Martin" <Martin.Thomson@andrew.com>
In-Reply-To: <8B0A9FCBB9832F43971E38010638454F03E7D067A9@SISPE7MB1.commscope.com>
Message-ID: <Pine.LNX.4.64.1004190159340.751@ps20323.dreamhostps.com>
References: <8B0A9FCBB9832F43971E38010638454F03E3F313ED@SISPE7MB1.commscope.com> <Pine.LNX.4.64.1004161940180.751@ps20323.dreamhostps.com> <8B0A9FCBB9832F43971E38010638454F03E7D0678C@SISPE7MB1.commscope.com> <Pine.LNX.4.64.1004190009190.751@ps20323.dreamhostps.com> <8B0A9FCBB9832F43971E38010638454F03E7D067A9@SISPE7MB1.commscope.com>
Content-Language: en-GB-hixie
Content-Style-Type: text/css
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset="US-ASCII"
Cc: Hybi <hybi@ietf.org>
Subject: Re: [hybi] Frame size
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: Mon, 19 Apr 2010 02:40:43 -0000

On Mon, 19 Apr 2010, Thomson, Martin wrote:
> > >
> > > You could complicate this if you like.  Perhaps each "fixed" 
> > > sequence is based on the output of a pseudorandom sequence, the seed 
> > > to which is assigned in the handshake.
> > 
> > Do you have any concrete suggestions for how we could do this? I'm not 
> > sure I follow.
> 
> Handshake contains: WebSocket-FrameSeed: <seed>
> 
> The peer that sends this header uses the number as follows:
> 
>   var PRNG prng = new PRNG(seed);
>   WS.prototype.sendFrame = function (data) {
>     this.buffer.send(prng.getNextBits(WS.FRAME_MARKER_LEN), WS.FRAME_MARKER_LEN);
>  
>     this.buffer.send(WS.BINARY_FRAME, WS.FRAME_TYPE_LEN);
> 
>     var binary = UTF8.encode(data);
>     this.buffer.send(binary.length, WS.FRAME_LENGTH_LEN);
>     this.buffer.send(binary, binary.length);
>  }
> 
> A receiver does the same, but uses the PRNG.getNextBits() to check that the frame was correctly terminated:
> 
>   if (this.buffer.read(WS.FRAME_MARKER_LEN) != prng.getNextBits(WS.FRAME_MARKER_LEN)) {
>     // ERROR: drop connection, throw exception, etc...
>   }  

I don't understand how this solves the problem of people mismeasuring 
strings. (I don't really follow the pseudocode above, either.)

My concern is that people will write this:

   send(WS.BINARY_FRAME);
   send(encodeLength(data.length));
   send(data);

...and their system will automatically convert the string "data" to UTF-8.

(As opposed to doing:

   var binary = UTF8.encode(data);
   send(WS.BINARY_FRAME);
   send(encodeLength(binary.length));
   send(binary);

...or the equivalent.)


> > Assuming you are asking for a longer rationale for the current 
> > handshake, please search for "the rationale" in this message for an 
> > explanation:
> > 
> >    http://www.ietf.org/mail-archive/web/hybi/current/msg01607.html
> 
> You have an HTTP client that is being duped into contacting a WebSockets 
> server.  I can understand that far, but I don't see what the attacker 
> gains.  The scenario needs more details.
> 
> Invent a scenario for me.  How does this allow the attacker to gain the 
> nuclear launch codes?

There's no way to extract data in such a scenario, as far as I am aware, 
unless the subprotocol supports a way to trigger data to be sent out of 
band. To use your analogy, the risk is not getting nuclear launch codes, 
it's just launching the nukes.

Suppose an author wrote a Web Socket server that launches nukes upon 
request. The server is in on a secure intranet, and all users are trusted, 
so there's no authentication required. The server therefore can ignore the 
handshake, and just needs to scan for frames that have the request.

There's no way for an attacker on hostile.example.com to open a Web Socket 
connection to nukes.intranet.example, since the browser would read the 
handshake from nukes.intranet.example before allowing a frame to be sent, 
and the handshake says that only the origin nukes.intranet.example is 
allowed. However, hostile.example.com can instead do an XHR or form 
submission to nukes.intranet.example, with the payload being carefully 
crafted to contain just a frame causing a nuke. The server would receive 
it, ignore the (wrong) handshake, see the frame, and set off the nukes. A 
worker browsing the Web with a computer on that intranet who happens to go 
to hostile.example.com could, without their knowledge, fire the nukes.

The new handshake works around this (as described in the message above) by 
requiring that the server prove that it checked the handshake. In the 
scenario above, the server would fail to find the right information to 
create that proof; there is a much better chance that the author would 
then bail rather than continue trying to listen for further frames.

(I considered making it even more secure by saying that the first byte of 
the MD5 sum that the author sends back in the handshake must be xored with 
the frame type byte, since then there's at best a 1/256 chance that the 
attacker will have a successful attack even if the server doesn't bail 
upon failing to find all the right bits, but that isn't a good tradeoff -- 
it makes debugging _much_ harder while making the protocol not that much 
more secure -- a few hundred attempts isn't many.)


> If this is as simple as a programmer forgetting the distinction between 
> /Upgrade: foo/ and /^Upgrade: foo/, then we're back to disagreeing on 
> the same old and tired topic.

Yes. The protocol would be very different if I had designed it for experts 
only. As I've said before, if it is the consensus of this working group 
that we should not design a protocol for amateurs, then we should start 
over. I have no objection to this working group designing a protocol for 
experts only; personally, though, I am interested in writing a protocol 
for amateurs. I don't mind if we do this here or elsewhere. I would, 
however, like to know whether that is an acceptable work product for this 
working group, because arguing about whether it is or not is not getting 
us anywhere and is apparently not something we can decide objectively.

-- 
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'