Re: [hybi] Websocket: two protocols into one, and Internet rules broken

Ian Fette (イアンフェッティ) <ifette@google.com> Thu, 16 June 2011 20:39 UTC

Return-Path: <ifette@google.com>
X-Original-To: hybi@ietfa.amsl.com
Delivered-To: hybi@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id EA78E11E8234 for <hybi@ietfa.amsl.com>; Thu, 16 Jun 2011 13:39:39 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -105.527
X-Spam-Level:
X-Spam-Status: No, score=-105.527 tagged_above=-999 required=5 tests=[AWL=0.149, BAYES_00=-2.599, FM_FORGED_GMAIL=0.622, HTML_MESSAGE=0.001, MIME_8BIT_HEADER=0.3, RCVD_IN_DNSWL_MED=-4, USER_IN_WHITELIST=-100]
Received: from mail.ietf.org ([64.170.98.30]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id w-F5IpCSU6FG for <hybi@ietfa.amsl.com>; Thu, 16 Jun 2011 13:39:38 -0700 (PDT)
Received: from smtp-out.google.com (smtp-out.google.com [216.239.44.51]) by ietfa.amsl.com (Postfix) with ESMTP id 5784811E82D6 for <hybi@ietf.org>; Thu, 16 Jun 2011 13:39:37 -0700 (PDT)
Received: from wpaz21.hot.corp.google.com (wpaz21.hot.corp.google.com [172.24.198.85]) by smtp-out.google.com with ESMTP id p5GKdbJI010993 for <hybi@ietf.org>; Thu, 16 Jun 2011 13:39:37 -0700
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=google.com; s=beta; t=1308256777; bh=A/ffpJpnrngEMcKqxFBgex5iJHc=; h=MIME-Version:Reply-To:In-Reply-To:References:Date:Message-ID: Subject:From:To:Cc:Content-Type; b=U1HsUHwWnvM+SdjBgvwON6CYFq+641oHnNZNBgjxrjwNo6hQi1Z5WO5dqU61qTKdN JRYkZnofNx0H02ms/xmdg==
Received: from iwg8 (iwg8.prod.google.com [10.241.66.136]) by wpaz21.hot.corp.google.com with ESMTP id p5GKdaw2025895 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <hybi@ietf.org>; Thu, 16 Jun 2011 13:39:36 -0700
Received: by iwg8 with SMTP id 8so2045604iwg.14 for <hybi@ietf.org>; Thu, 16 Jun 2011 13:39:36 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=beta; h=domainkey-signature:mime-version:reply-to:in-reply-to:references :date:message-id:subject:from:to:cc:content-type; bh=XD/6fR3jIXRw2KjxdRS33oeATvrW74AoNHVm/TzgCKM=; b=GTgTy4kdrKZ++zEMmgUzGkIEN3hzLYui0OW4PFCVB7jAGS+xw8zUIXrEgHnBgEFWch 7o//y8POJyso3dziVmMw==
DomainKey-Signature: a=rsa-sha1; c=nofws; d=google.com; s=beta; h=mime-version:reply-to:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; b=O+0AtLibYOXD8KZsVeLIxKu1ASGOOct3I8x14gUF7owZGNWMQKK3afwrvD2ugVrVRL +rknjwHHv6DIK4My75Hw==
MIME-Version: 1.0
Received: by 10.231.41.69 with SMTP id n5mr1185742ibe.83.1308256775957; Thu, 16 Jun 2011 13:39:35 -0700 (PDT)
Received: by 10.231.33.8 with HTTP; Thu, 16 Jun 2011 13:39:35 -0700 (PDT)
In-Reply-To: <BANLkTin2000Q8=LUuuUqkfkX_GRrYAnNDw@mail.gmail.com>
References: <BANLkTim4pKwx6wYC3WwXFWET+gx0bnjigQ@mail.gmail.com> <4DFA08A5.3010608@weelya.com> <BANLkTi=JGeFmkYcwqQJ_xe=3CGrXwHxHPg@mail.gmail.com> <4DFA1173.9050509@weelya.com> <BANLkTi=LAiw+JvCOc3VPrXnmog7AkSWwCw@mail.gmail.com> <4DFA15E9.50800@weelya.com> <BANLkTikdUneox_4tpMm-EjXPQEEbN7sF4w@mail.gmail.com> <BANLkTik4y_fRd3pEuPdrwESb7ftdbuvk9w@mail.gmail.com> <BANLkTin2000Q8=LUuuUqkfkX_GRrYAnNDw@mail.gmail.com>
Date: Thu, 16 Jun 2011 13:39:35 -0700
Message-ID: <BANLkTi=w2SC5MFA21NrYhsV-ZyN5hzrSiQ@mail.gmail.com>
From: "Ian Fette (イアンフェッティ)" <ifette@google.com>
To: Joel Martin <hybi@martintribe.org>
Content-Type: multipart/alternative; boundary="0015177407d467ebab04a5da44ad"
X-System-Of-Record: true
Cc: hybi@ietf.org
Subject: Re: [hybi] Websocket: two protocols into one, and Internet rules broken
X-BeenThere: hybi@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
Reply-To: ifette@google.com
List-Id: Server-Initiated HTTP <hybi.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/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, 16 Jun 2011 20:39:40 -0000

Historically, many servers are lazy. They will not bother validating
whatever the client sends, and will just return some value and then get
exploited. By forcing the server to prove something to the client, we
essentially also force the server to validate at least part of the client's
handshake (rather than just hardcoding in some 101 Upgrade WS response). So,
by making the server prove something to the client, it's a way of forcing
the server to actually take some steps that have a side effect of protecting
it (e.g. this /forces/ the server to parse the Sec-WebSocket-Key header.)

2011/6/16 Joel Martin <hybi@martintribe.org>

> Ian,
>
> I should have been more clear. I understand why the client and server have
> to validate each other, it's the text of the paragraph in the draft that I'm
> confused about and I posted here because I think the draft text at least
> needs clarification.
>
>     "Finally, the server has to prove to the client that it received the
>     client's WebSocket handshake, ..."
>
> - Good so far
>
>     "...so that the server doesn't accept connections that are not
>     WebSocket connections."
>
> - What does proving to the client have to do with the _server_ refusing
> non-websockets connections? Perhaps this is supposed to be "...so that the
> client will not procede with connections to non-WebSocket servers."
>
>     "This prevents an attacker from tricking a WebSocket server by sending
>     it carefully-crafted packets using |XMLHttpRequest| or a |form|
> submission."
>
> - Again, what does proving to the client have to do with tricking the
> WebSocket server? Maybe this should really be "This prevents an attacker
> from tricking a non-WebSocket server by sending it carefully-crafted
> WebSocket packets because a non-WebSocket server will not return a correct
> Sec-WebSocket-Accept value during the handshake".
>
> Regards,
>
> Joel Martin
>
> 2011/6/16 Ian Fette (イアンフェッティ) <ifette@google.com>
>
> Sec-WebSocket-Accept uses a GUID defined in the protocol and the key from
>> the handshake to prove that the remote end is indeed a websocket server as
>> you point out. The other part is that Sec-WebSocket-Accept takes the key
>> from the Sec-WebSocket-Key header, which XHR cannot send and thus the server
>> doesn't have the information necessary to generate the Accept value as there
>> is no key from the client.
>>
>> The original question you link to is basically "why does the server have
>> to answer a challenge", and it breaks down into two parts:
>>
>> 1. Force server to validate that the client is a WebSocket client (by
>> making it use a value from Sec-WebSocket-Key along with the GUID, we ensure
>> that the server actually checks for the presence of Sec-WebSocket-Key.)
>> 2. Let the client validate that the server is actually a WebSocket server
>> (by checking that Sec-WebSocket-Accept is properly computed).
>>
>> #1 lets the server be sure it's not responding to some random XHR request,
>> #2 lets the browser know that it's safe to connect and that it's
>> communicating to a WebSocket server and not some non-WS target.
>>
>> On Thu, Jun 16, 2011 at 8:54 AM, Joel Martin <hybi@martintribe.org>wrote:
>>
>>> I started to try and answer this StackOverflow question about the
>>> protocol text and realized that I didn't understand it as well as I thought:
>>>
>>> http://stackoverflow.com/questions/6372252/why-does-the-server-in-a-websocket-request-have-to-answer-a-challenge
>>>
>>> The question is related to this paragraph (which has been in the drafts
>>> for a while unchanged):
>>>
>>>     Finally, the server has to prove to the client that it received the
>>>     client's WebSocket handshake, so that the server doesn't accept
>>>     connections that are not WebSocket connections.  This prevents an
>>>     attacker from tricking a WebSocket server by sending it carefully-
>>>     crafted packets using |XMLHttpRequest| or a |form| submission.
>>>
>>> I can see how the Sec-WebSocket-Accept would prevent a WebSocket client
>>> from being tricked into connecting to a non-WebSocket server. However, I'm
>>> having difficulty understanding how the Sec-WebSocket-Accept header would
>>> prevent a XMLHttpRequest from succeeding to a WebSockets server since it is
>>> sent from the server. I am aware of the prohibition against "Sec-" headers
>>> in the client to server direction. Is there a requirement that
>>> XMLHttpRequest responses with unrecognized "Sec-" headers be rejected by
>>> user agents (and if so does this only apply in the browser case)?
>>>
>>> It's likely I just don't have enough context to understand the paragraph,
>>> but perhaps it could be clarified a bit.
>>>
>>> Regards,
>>>
>>> Joel Martin
>>>
>>> _______________________________________________
>>> hybi mailing list
>>> hybi@ietf.org
>>> https://www.ietf.org/mailman/listinfo/hybi
>>>
>>>
>>
>