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

Maciej Stachowiak <mjs@apple.com> Thu, 30 September 2010 01:51 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 596973A6D14 for <hybi@core3.amsl.com>; Wed, 29 Sep 2010 18:51:44 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -105.749
X-Spam-Level:
X-Spam-Status: No, score=-105.749 tagged_above=-999 required=5 tests=[AWL=-0.250, BAYES_00=-2.599, GB_ABOUTYOU=0.5, J_CHICKENPOX_33=0.6, 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 I9uwJOh3Bl5n for <hybi@core3.amsl.com>; Wed, 29 Sep 2010 18:51:43 -0700 (PDT)
Received: from mail-out3.apple.com (mail-out.apple.com [17.254.13.22]) by core3.amsl.com (Postfix) with ESMTP id 111223A6D08 for <hybi@ietf.org>; Wed, 29 Sep 2010 18:51:43 -0700 (PDT)
Received: from relay11.apple.com (relay11.apple.com [17.128.113.48]) by mail-out3.apple.com (Postfix) with ESMTP id 9A113AC17346 for <hybi@ietf.org>; Wed, 29 Sep 2010 18:52:27 -0700 (PDT)
X-AuditID: 11807130-b7cf8ae0000058d2-fd-4ca3ed5b9155
Received: from gertie.apple.com (gertie.apple.com [17.151.62.15]) by relay11.apple.com (Apple SCV relay) with SMTP id 15.3D.22738.B5DE3AC4; Wed, 29 Sep 2010 18:52:27 -0700 (PDT)
MIME-version: 1.0
Content-transfer-encoding: 7bit
Content-type: text/plain; charset="us-ascii"
Received: from [66.109.106.76] by gertie.apple.com (Sun Java(tm) System Messaging Server 6.3-7.04 (built Sep 26 2008; 32bit)) with ESMTPSA id <0L9J006A3EJBZ370@gertie.apple.com> for hybi@ietf.org; Wed, 29 Sep 2010 18:52:27 -0700 (PDT)
Sun-Java-System-SMTP-Warning: Lines longer than SMTP allows found and truncated.
From: Maciej Stachowiak <mjs@apple.com>
In-reply-to: <AANLkTi=ieqL=mGW3POW7g0QEs4XWYT=zq_BKiWb2BxtK@mail.gmail.com>
Date: Wed, 29 Sep 2010 18:52:21 -0700
Message-id: <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>
To: Greg Wilkins <gregw@webtide.com>
X-Mailer: Apple Mail (2.1081)
X-Brightmail-Tracker: AAAAAA==
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 01:51:44 -0000

On Sep 29, 2010, at 3:08 PM, Greg Wilkins wrote:

> On 30 September 2010 02:47, Maciej Stachowiak <mjs@apple.com> wrote:
>>> Why is hex encoding simpler to inject than the space/char injected
>>> decimal encoding?
>> 
>> Because you can't inject whitespace into the resource name in the request line.
> 
> It is very hard to imagine a server that is so broken that it will
> allow injection of fully formed HTTP requests, responses into a URL,
> complete with CRLF etc. but that will not allow spaces to be injected.

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.

> 
> Also, the attacks described do not need to inject the space encoded
> fields.  They are part of the request and the attacker is happy for
> the server to just ignore them.  The attacker is trying to inject a
> valid 101 response.

We're clearly not using "inject" in the same way. When I say "injected", I mean "caused by the attacker to be inserted into a browser-generated request that they do not fully control"

> 
> Unless you are concerned that somehow the WS server will see the URL
> in the upgrade request as a second upgrade request??

I don't see how this relates to my scenario. It doesn't involve a second upgrade request.

> but simple WS servers are not going to process multiple HTTP requests
> and complex ones are going to have real HTTP parsers that should not
> be vulnerable to such an attack - if they were, then they are so
> broken that spaces are not going to make a difference, because you
> must also be able to inject CRLF.

You only need to be able to inject CRLF if something about the server-side check is required to look at multiple lines. Imagine poorly coded regexp-matching parsers that look at one line at a time.


> 
> 
> 
> 
>>> The white space fields originate from the client and do not need to be
>>> injected into
>>> the server response.
>>> 
>>> Can you explain any scenario where a HTTP client could somehow send Sec- fields
>>> without spaces, but could not send ones with spaces?
>> 
>> Sticking something that looks like a Sec- header into the request line is possible (that is under the attacker's control with both WebSocket and HTTP APIs) but you can't include whitespace - it will get stripped or percent-escaped.
> 
> Injecting such things into request lines is normally part of an attack
> to cause the server to echo that content back as part of a response.
> There is no benefit of putting Sec- headers into the response.

Perhaps, but I don't believe that is the scenario the whitespace encoding was meant to address. I don't think the whitespace encoding of the nonce is particularly powerful, but it does have an effect.

> 
> Having Sec-header content in the request line is not going to make the
> server see that as another HTTP request or as part of the current HTTP
> request - unless it is so broken that CRLF can be inject, in which
> case I don't think spaces are much protection.

The client can't generally be tricked into putting CRLF into the request line (though occasionally a bug like that crops up and creates security vulnerabilities).

> 
>> For the record, I don't think the unframed random bytes in the request add any security value.
> 
> Then why are you fighting so hard against my reasonable proposals?

I'm not "fighting against" your proposal, I am explaining how your proposed handshake creates security risk. I also think the current handshake creates security risk (maybe a tiny iota less).

> 
> Couldn't you just have said +1 to framing those bytes, but I'm a
> little worried about taking the spaces out???
> Did you really need to start this whole thread questioning my
> capabilities to understand a cross protocol attack?

I jumped in this thread solely to inject information about the risks of cross-protocol attacks, since it seemed like no one was thinking about the HTTP vs. WebSocket attack vector. At that point, people reacted skeptically and/or indignantly, so I tried to explain further. I am still not sure I have fully explained the risks adequately.

You made security claims about your handshake proposal - that is the sort of thing that invites scrutiny and security review. My comments so far are not even a particularly deep review.

> 
>> Personally, I would prefer if failure-detection mechanisms were kept separate from security mechanisms if possible.
> 
> I have long argued for that.   In fact I believe that it would be
> sufficient to put the hash into a response header.
> However, some appear to have concerns with that - so I was proposing
> minimal changes to try to fix the broken handshake.
> If you think we should go further, then that is no reason to argue
> against the modest proposals that I have made:
> 
>  + frame the random bytes as websocket frames
>  + don't send ws frames until after 101.
>  + use a simple hex encoding for the nonce

My alternate proposal is that we drop HTTP-based handshakes entirely in favor of TLS+NPN. But I have also suggested several specific ways to make your proposed scheme more robust (server-side nonce, one-time-pad of the data frames, etc).

Regards,
Maciej