Subject: [hybi] WS frames as HTTP requests/responses

From: Greg Wilkins <[email-masked]>
Date: Sun, 10 Oct 2010 09:31:26 +1100

0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-------+-+-------------+-------------------------------+
     |M|R|R|R| opcode|R| Payload len |    Extended payload length    |
     |O|S|S|S|  (4)  |S|     (7)     |             (16/63)           |
     |R|V|V|V|       |V|             |   (if payload len==126/127)   |
     |E|1|2|3|       |4|             |                               |

get   0 1 1 0 0 1 1 1 0 1 1 0 0 1 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 0 0 0
GET   0 1 0 0 0 1 1 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 0 0 0 1 0 0 0 0 0
post  0 1 1 1 0 0 0 0 0 1 1 0 1 1 1 1 0 1 1 1 0 0 1 1 0 1 1 1 0 1 0 0
POST  0 1 0 1 0 0 0 0 0 1 0 0 1 1 1 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 0 0

Looking at the above, we can see that in order to send a WS frame that
looks like a GET or a POST,
the attacker will need to be able to set RSV bits.   GET requests need
an opcode 7, which is currently
reserved. POST requests need an opcode of 0 which is currently the
continuation frame an illegal
without a prior MORE frame

Currently reserve bits and opcodes are not under the control of the
application, and RSV bits
are not utilized. So initially there is no risk WS frame looking like
a GET or POST.  However, it
may be a consideration once RSV bits are being used by extension (if
we don't have sufficient
confidence in the handshake).

Neither trigger a medium or long frame, and the frame lengths are 101,
69, 111, 79 bytes, which are
all easily achievable and have some space to contain the remainder of
a spoofed request.

There is no mechanism for the browser to inject any required credentials
(cookies or BASIC/DIGEST), so an attacher would need to find another
way to obtain those.

Looking the other way around, a pong packet carrying 16 bytes of
hashed nonce would look like

   0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 xx xx xx xx xx xx xx xx xx xx xx xx
xx xx xx xx

  ETX  DLE  (16x random characters)

There is little chance of this being mistaken as a legal HTTP request
and the ETX character alone is
probably sufficient for most servers to send 400 Bad Request and close
the connection.  This
assumption should be tested against common servers.

HTTP responses will begin with HTTP, which will be interpreted as a WS
as follows

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-------+-+-------------+-------------------------------+
     |M|R|R|R| opcode|R| Payload len |    Extended payload length    |
     |O|S|S|S|  (4)  |S|     (7)     |             (16/63)           |
     |R|V|V|V|       |V|             |   (if payload len==126/127)   |
     |E|1|2|3|       |4|             |                               |
      0 1 0 0 1 0 0 0 0 1 0 1 0 1 0 0

This has RSV1 bit set and an opcode of 8, and payload length of 84
bytes.  Initially opcode 8 is unallocated
resulting in this frame being ignored.   If there is concern that HTTP
responses may be interpreted as
a WS frame, then we could reassign opcode 8 to be connection close.

There does not appear to be much scope for WS frames to be
misinterpreted as HTTP requests or
vice versa.  There are probably a few small changes we can make to
op-code allocation to further
improve the situation.

---

From: Bjoern Hoehrmann <[email-masked]>
Date: Sun, 10 Oct 2010 01:18:36 +0200

(The more interesting cases would be the "opcodes" 10 and 13 as servers
ignore empty lines when expecting a request.)
-- 
Björn Höhrmann · mailto:[email-masked] · http://bjoern.hoehrmann.de
Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/

---

From: Scott Ferguson <[email-masked]>
Date: Sat, 09 Oct 2010 17:55:29 -0700

Greg Wilkins wrote:
> Looking at the above, we can see that in order to send a WS frame that looks like a GET or a POST,
>
> the attacker will need to be able to set RSV bits.   GET requests need an opcode 7, which is currently
> reserved. POST requests need an opcode of 0 which is currently the continuation frame an illegal 

If we flipped the MORE bit to a FIN bit, the PONG would be non-ascii 
with the initial high bit set, which is never a valid HTTP request.

-- Scott

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 11 Oct 2010 15:50:37 +1100

On 10 October 2010 11:55, Scott Ferguson <[email-masked]> wrote:

>> get   0 1 1 0 0 1 1 1 0 1 1 0 0 1 0 1 0 1 1 1 0 1 0 0 0 0 1 0 0 0 0 0 GET
>>   0 1 0 0 0 1 1 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 0 0 0 1 0 0 0 0 0
>>
>> continuation frame an illegal without a prior MORE frame
>>
>
> If we flipped the MORE bit to a FIN bit, the PONG would be non-ascii with
> the initial high bit set, which is never a valid HTTP request.

Nice idea!