Re: [hybi] Extensibility mechanisms?

Scott Ferguson <ferg@caucho.com> Thu, 22 July 2010 16:36 UTC

Return-Path: <ferg@caucho.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 C4C983A69B9 for <hybi@core3.amsl.com>; Thu, 22 Jul 2010 09:36:31 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.299
X-Spam-Level:
X-Spam-Status: No, score=-2.299 tagged_above=-999 required=5 tests=[AWL=-0.300, BAYES_00=-2.599, J_CHICKENPOX_22=0.6]
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 e5BYjEQQ1SDn for <hybi@core3.amsl.com>; Thu, 22 Jul 2010 09:36:30 -0700 (PDT)
Received: from smtp114.biz.mail.mud.yahoo.com (smtp114.biz.mail.mud.yahoo.com [209.191.68.79]) by core3.amsl.com (Postfix) with SMTP id 4F4893A6989 for <hybi@ietf.org>; Thu, 22 Jul 2010 09:36:30 -0700 (PDT)
Received: (qmail 14187 invoked from network); 22 Jul 2010 16:36:44 -0000
Received: from [192.168.1.11] (ferg@66.92.8.203 with plain) by smtp114.biz.mail.mud.yahoo.com with SMTP; 22 Jul 2010 09:36:44 -0700 PDT
X-Yahoo-SMTP: L1_TBRiswBB5.MuzAo8Yf89wczFo0A2C
X-YMail-OSG: JaCnTTgVM1l3xj61x3h2UqQMasQsR97PB3ES5gJs8SMse4X xVtweShBeBKu0SI_4sTCJqYU4P5WQt9vwWUa8BHdmDog3ezfJ7TTbiJ2dz1Z HkR1t75Ugz7Z_K7JT86IFSfLBgJD8FGGsL6aGfh27o1WYr0PBDMe5tFrxODU 7bdvBO0MYlF19m_M935O0_jKrNu85EH3_sDX1cHLSvRtMEmBKwhq_tejxKi3 M7.v.QJBrceETUDuP0jqEu17Ht7Pt1AM3P2b7YO6wOK8Lby54LmYAMyj9ur5 4dJH5XGijzJI35PPfha5k4HfHUGGgp09pvilBbW9B71R.kO_XZJuOUQ--
X-Yahoo-Newman-Property: ymail-3
Message-ID: <4C487392.7080303@caucho.com>
Date: Thu, 22 Jul 2010 09:36:34 -0700
From: Scott Ferguson <ferg@caucho.com>
User-Agent: Thunderbird 2.0.0.24 (X11/20100411)
MIME-Version: 1.0
To: Maciej Stachowiak <mjs@apple.com>
References: <h2w5c902b9e1004152345j992b815bz5f8d38f06a19181a@mail.gmail.com> <4BCAB2C1.2000404@webtide.com> <B9DC25B0-CD21-44E7-BD9B-06D0C9440933@apple.com> <4BCB7829.9010204@caucho.com> <Pine.LNX.4.64.1004182349240.751@ps20323.dreamhostps.com> <4BCC0A07.9030003@gmx.de> <Pine.LNX.4.64.1004190753510.23507@ps20323.dreamhostps.com> <4BCC111C.90707@gmx.de> <Pine.LNX.4.64.1004190837570.23507@ps20323.dreamhostps.com> <4BCC204D.30004@gmx.de> <z2gad99d8ce1004190822ne4dd36b6v54d63efcc448e840@mail.gmail.com> <Pine.LNX.4.64.1007202204270.7242@ps20323.dreamhostps.com> <AANLkTikkfdlUxQ0MGNvVQKa5gfovkGHWdCgyN9juKSQJ@mail.gmail.com> <4C462F9E.9030207@caucho.com> <Pine.LNX.4.64.1007212153110.7242@ps20323.dreamhostps.com> <AANLkTiku76oSucTNDFdwgsFBNFa_cCpC-YktTnMfX47-@mail.gmail.com> <4C479130.4020500@caucho.com> <B6EA60FA-53BB-49AD-82B4-D1E7B460C297@apple.com>
In-Reply-To: <B6EA60FA-53BB-49AD-82B4-D1E7B460C297@apple.com>
Content-Type: text/plain; charset="ISO-8859-1"; format="flowed"
Content-Transfer-Encoding: 7bit
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 16:36:31 -0000

Maciej Stachowiak wrote:
> On Jul 21, 2010, at 5:30 PM, Scott Ferguson wrote:
>
>   
>> The counterproposal at
>>
>> http://hessian.caucho.com/websockets/draft-ferg-hybi-websockets-latest.html
>>
>> not complicated at all: it's a trivial protocol, and yet it solves the HyBi requirements, including requirements that the current draft ignores, as well as being extensible to muxing requirements.
>>     
>
> Can you explain how this proposal provides an HTTP-compatible upgrade in the non-TLS case? Or how it provides protection against cross-protocol attacks? I think those are two pretty important requirements, and it is not obvious to me how they are met.
>   
Actually, let me explain how the non-HTTP version was designed to handle 
cross-protocol attacks, because I didn't explain the reasoning behind 
the design in the draft.

I) Initial HELLO line

The initial line for both server and client responses is:

  %x80.x02.NN.NN WebSocket/1.0 LF

Deliberately designed properties of that line:

  1. Since it's a fixed-length line, there's no opportunity for URL or 
METHOD-style attacks.

  2. Since it's a line, terminated by LF, it validates against 
text-based protocols, even though this is a binary protocol. (Potential 
NN.NN attacks can be enumerated and checked.)

  3. Since the only variation is the two bytes NN.NN, 65536 values, all 
possible initial HELLO lines can be enumerated and tested against other 
protocols.

  4. Since it's not a legal HTTP line, HTTP servers and clients will 
reject it.

  5. Browser HTTP clients cannot generate that line.

  6. Since the initial byte is neither valid ASCII nor is it valid 
UTF-8, no validating ASCII/UTF-8 server will accept that line, and no 
ASCII/UTF-8 client can generate that line.

  7. The fixed "WebSocket/1.0" validates the protocol itself. Boring, 
but necessary.

I'll maintain the following properties are true of that initial line:

  1. No HTTP client can spoof that line (unless it has full binary 
control over the HTTP method, but that security hole could spoof any 
protocol).

  2. That line will be rejected by any HTTP server (all 64k variations 
of it).

  3. Clients of other protocols cannot spoof that line (again, unless 
they have full binary control over their initial bytes, and obviously 
TCP can "spoof" the line).

  4. binary and text servers which validate their initial line cannot be 
spoofed by it.

That covers validating binary and text protocols, but there's still the 
case of protocols like SMTP that discard invalid lines.

II) Handling recovery-based text protocols like SMTP

The next required lines from the request looks like:

  url: <restricted utf-8> LF

where the restrictions include forbidding LF itself.

This is a HTTP header without the line-folding.  If a SMTP 
implementation protects against HTTP headers (I checked against 
postfix), it protects against this WebSocket header. If the SMTP 
implementation accepts all invalid lines, there's really nothing you can 
do, except for the WebSocket client to wait for the server response.

III) header/url/origin issues

The "url:", "origin:", "protocol:" headers and their semantics are 
copied from the official WebSocket draft. If there's a problem with 
them, there's a problem with the official draft. (If there's an error in 
transcription, that's easily fixed.)

IV) nonce/digest

In practice, these cover validating protocols. However, it's also 
possible to force the server to prove that it's an active WebSocket 
server.  Adding a "nonce:" header to the client, and requiring the 
server to calculate a "digest:" header is proof that the server is a 
valid WebSocket server. (I personally don't think this is necessary, but 
the group may disagree.)

V) pipelining/multiple packet handshake

Pipelining data means the client is sending data before looking at the 
server's response. If this is unacceptable, the client must wait for the 
response.  There's no protocol design around this issue. You need to 
choose one behavior or the other. My draft choose pipelining. The group 
could choose the reverse.

VI) Does this cover everything?

Since the HELLO line is a fixed-length sequence (with finite 64k 
variations), it's possible to prove if it can spoof any specific 
protocol or if a specific protocol can be spoofed by it.

For example, it's possible to prove that this initial line is invalid 
HTTP and that no valid HTTP can match this line. In this case the proof 
is trivial because the initial byte is an invalid first byte of HTTP.

It's also possible to exhaustively test any specific 
non-WebSocket-protocol implementation against all possible HELLO 
attacks, because all possible HELLO lines are enumerable. You don't have 
to guess if an IRC server will reject a WebSocket HELLO; you can test it.

In a similar way, it's possible to reason about non-validating or 
partially validating servers. For example, if the HTTP server does not 
validate ASCII/UTF-8, but merely scans for SP and CR/LF, the WebSocket 
request line interpreted as HTTP is still an invalid request. And even 
if one of the NN is a SP and you have a truly brain-dead HTTP server, 
the HTTP method for the hypothetical broken server isn't a valid method. 
And if the server doesn't even validate that case, it's just plain broken.

So, even though the handshake wasn't my main focus of that draft, I do 
believe it covers cross-protocol scripting issues better than HTTP 
itself does. Obviously, my HTTP handshake version has identical security 
behavior with the official draft.

-- Scott