Re: [hybi] Redesigning the Web Socket handshake

Maciej Stachowiak <mjs@apple.com> Wed, 03 February 2010 08:20 UTC

Return-Path: <mjs@apple.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 7F4BF3A6A6B for <hybi@core3.amsl.com>; Wed, 3 Feb 2010 00:20:01 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -106.413
X-Spam-Level:
X-Spam-Status: No, score=-106.413 tagged_above=-999 required=5 tests=[AWL=0.185, BAYES_00=-2.599, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_MED=-4, USER_IN_WHITELIST=-100]
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 kAXCIk2IXb4T for <hybi@core3.amsl.com>; Wed, 3 Feb 2010 00:20:00 -0800 (PST)
Received: from mail-out4.apple.com (mail-out4.apple.com [17.254.13.23]) by core3.amsl.com (Postfix) with ESMTP id 5F1DF3A6A66 for <hybi@ietf.org>; Wed, 3 Feb 2010 00:20:00 -0800 (PST)
Received: from relay15.apple.com (relay15.apple.com [17.128.113.54]) by mail-out4.apple.com (Postfix) with ESMTP id C69B389E52C0 for <hybi@ietf.org>; Wed, 3 Feb 2010 00:20:41 -0800 (PST)
X-AuditID: 11807136-b7bafae000000e8d-f9-4b6931d97d07
Received: from elliott.apple.com (elliott.apple.com [17.151.62.13]) by relay15.apple.com (Apple SCV relay) with SMTP id 27.4C.03725.9D1396B4; Wed, 3 Feb 2010 00:20:41 -0800 (PST)
MIME-version: 1.0
Content-type: multipart/alternative; boundary="Boundary_(ID_z5ORJyZpITW1ZmaOTDiVgw)"
Received: from [17.151.86.222] by elliott.apple.com (Sun Java(tm) System Messaging Server 6.3-7.04 (built Sep 26 2008; 32bit)) with ESMTPSA id <0KX900LKUB6HEJ80@elliott.apple.com> for hybi@ietf.org; Wed, 03 Feb 2010 00:20:41 -0800 (PST)
From: Maciej Stachowiak <mjs@apple.com>
In-reply-to: <9A862D96-FD32-4532-BDBE-AAC5C82DB954@apple.com>
Date: Wed, 03 Feb 2010 00:20:40 -0800
Message-id: <BD4D49B1-6EB0-425E-BA3C-AE34DE826739@apple.com>
References: <Pine.LNX.4.64.1002012305000.21600@ps20323.dreamhostps.com> <4B676E8C.70804@webtide.com> <Pine.LNX.4.64.1002020311030.3846@ps20323.dreamhostps.com> <4B679E2C.2080502@webtide.com> <FD440FEA-9F53-4F4C-8AA5-98B23318F0F7@apple.com> <5c902b9e1002021431w25768b2eu4e21244f080bed25@mail.gmail.com> <9A862D96-FD32-4532-BDBE-AAC5C82DB954@apple.com>
To: Maciej Stachowiak <mjs@apple.com>
X-Mailer: Apple Mail (2.1077)
X-Brightmail-Tracker: AAAAAQAAAZE=
Cc: hybi@ietf.org
Subject: Re: [hybi] Redesigning the Web Socket handshake
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: Wed, 03 Feb 2010 08:20:01 -0000

On Feb 2, 2010, at 9:22 PM, Maciej Stachowiak wrote:

> There are many possible variants, but here is an example of what the handshake request and response could look like (the hash used here is MD5; we could use a weaker hash that is faster to compute however):
> 
> Handshake from the client:
> 
>        GET /demo HTTP/1.1
>        Upgrade: WebSocket
>        Connection: Upgrade
>        Host: example.com
>        Origin: http://example.com
>        WebSocket-Protocol: sample
>        WebSocket-Nonce: 2d1283cf01e0e9f562989f0781450e7e
> 
> Response from the server:
> 
>        HTTP/1.1 101 Web Socket Protocol Handshake
>        Upgrade: WebSocket
>        Connection: Upgrade
>        WebSocket-Origin: http://example.com
>        WebSocket-Location: ws://example.com/demo
>        WebSocket-Protocol: sample
>        WebSocket-Nonce-Hash: 8ba7ca1e53376d29842e88d0f9db6978
> 
> The status line must come first, but order and capitalization of all request and response headers would be free. If we wanted to, we could even allow the status line to use any HTTP version.
> 
> A possible variant would be to include the nonce hash in the status line instead of in a header. But I think header is probably better.

I asked a security expert to review this and he had two suggestions:

1) Include the nonce hash in the status line. The strongest protection against cross-protocol attacks comes in the first few bytes, according to him, so it should be as early as possible.

2) The hash should also include the request origin and some fixed WebSocket-specific string (e.g. "WebSocket::"). (He actually suggested 'HMAC the string "Web
Socket::" and origin of WebSocket request using the nonce as a key' but I'm not sure if he was serious.)

Here is an example of the server response with the hash in the status line, and it is actually the MD5 hash of "WebSocket::<ORIGIN> <NONCE>" (i.e. "WebSocket::http://example.com 2d1283cf01e0e9f562989f0781450e7e").

       HTTP/1.1 101 Web Socket Protocol Handshake 2daff5fe4d1295d48697c3f1f4ab9538
       Upgrade: WebSocket
       Connection: Upgrade
       WebSocket-Origin: http://example.com
       WebSocket-Location: ws://example.com/demo
       WebSocket-Protocol: sample

Regards,
Maciej