Subject: [hybi] Rejecting client messages with mask=0 (X^0=X)

From: "Bemmel, Jeroen Van (Jeroen Van)" <[email-masked]>
Date: Sun, 18 Sep 2011 22:06:48 +0200

All,

Reading the latest draft, I was wondering if the server should actively reject a "masked" client message with mask set to 0 (i.e. 4 zero bytes). If not, an attacker could still craft a valid message on the wire at will.

Not sure if this addresses any specific security threats, but the draft could say:
*       The client MUST NOT use a mask value of all 0's
*       The server MUST silently discard a client message with MASK=1 and a mask value set to all 0's, and SHOULD close the connection upon reception of such a message

Or something along these lines.

Regards,
Jeroen

---

From: John Tamplin <[email-masked]>
Date: Sun, 18 Sep 2011 16:40:58 -0400

On Sun, Sep 18, 2011 at 4:06 PM, Bemmel, Jeroen Van (Jeroen Van) <
[email-masked]> wrote:

>  Reading the latest draft, I was wondering if the server should actively
> reject a “masked” client message with mask set to 0 (i.e. 4 zero bytes). If
> not, an attacker could still craft a valid message on the wire at will.
>
>    - The client MUST NOT use a mask value of all 0’s
>    - The server MUST silently discard a client message with MASK=1 and a
>    mask value set to all 0’s, and SHOULD close the connection upon reception of
>    such a message
>
>

If the attacker controls mask selection, then they can already do what they
want.  If the attacker has to assume the mask is random, assuming the mask
is 0 and sending the attack text is just as likely to succeed as assuming
any other mask value and sending the attack text XOR'd with that.

So, I don't think it actually increases security at all, and it merely adds
special cases for choosing the mask and verifying it.

-- 
John A. Tamplin
Software Engineer (GWT), Google

---

From: Bjoern Hoehrmann <[email-masked]>
Date: Sun, 18 Sep 2011 22:44:53 +0200

* Bemmel, Jeroen Van (Jeroen Van) wrote:
>reject a "masked" client message with mask set to 0 (i.e. 4 zero bytes).
>If not, an attacker could still craft a valid message on the wire at
>will.

An attacker can send payload `xor` mask to this effect whatever the mask
is, if he can predict the mask. If he cannot predict it then it does not
matter in the grand scheme of things what the mask is as he can't adjust
the payload to the mask. In principle a server could use heuristics to
detect clients that appear to use insufficiently random masks (like when
all frames use the same mask, or the value increments by one each time,
and so on) but there is little point in doing that.
-- 
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: Greg Wilkins <[email-masked]>
Date: Mon, 19 Sep 2011 09:54:07 +1000

> and so on) but there is little point in doing that.

More importantly, it is actually impossible for a server to tell if a
mask is predictable or not.   Many random number generators in common
usage are predictable if you know their internal state, so a server
can still see a stream of perfectly distributed random masks and an
attacker can still send text in the clear... if they have managed to
hack the state of the clients random number generator.

Distressingly, this can be surprisingly easy!  When jetty used the
standard java random generator seeded with current time for session
IDs, some maths whiz came up with a hack that given 10 recent session
IDs, 30 minutes of CPU (10 years ago), he could have a 1 in 32 guess
at the next session ID.

Given that these kinds of attacks rely on a compromised server, then
there is ample scope for an evil server to capture lots of mask
samples from the client and crunch the numbers to try and predict
future masks.   The defence against this is that common browsers with
open source simply have to use robust random number generators, which
I'm sure they do.   But if they don't then it is not the
responsibility of the servers to attempt to do the impossible analysis
to evaluate the random number generator used by the client.

cheers

---

From: Bjoern Hoehrmann <[email-masked]>
Date: Mon, 19 Sep 2011 02:26:01 +0200

* Greg Wilkins wrote:
>I'm sure they do.

Actually this will require careful checking as vendors ship their imple-
mentations of the finalized protocol. Using the wrong random number ge-
nerator, or using the right one incorrectly, is a fairly common problem
in browsers and much more so with other implementations. Picking CPAN's
Protocol::WebSocket as random example, the code there is

  # Not sure if perl provides good randomness
  my $mask = $self->{mask} || rand(2**32);

On Windows, ActiveState's ActivePerl by default comes with only 16 bits
of randomness, as I found out when implementing some Websocket masking
related thing. Of course, with non-browser implementations you do not
generally have the "attacker provides payload" and other problems that
make this vaguely problematic. (BCC-ing the relevant bug tracker.)
-- 
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: "Thomson, Martin" <[email-masked]>
Date: Mon, 19 Sep 2011 09:32:43 +0800

If a server is likely to reject unmasked frames, your random number generation needs to ensure that it doesn't generate a 0 mask:

  long mask = (random.nextDouble() * 0xffffffffL) + 1;

---

From: Peter Thorson <[email-masked]>
Date: Sun, 18 Sep 2011 21:18:12 -0500

A frame with the mask bit set and a mask key of 0 is still a masked frame though is it not? Shouldn't the unmasked frames that the server must reject per draft 15 be ones with the mask bit clear?

On Sep 18, 2011, at 20:32 , Thomson, Martin wrote:

> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi

---

From: "Thomson, Martin" <[email-masked]>
Date: Mon, 19 Sep 2011 11:17:37 +0800

On 2011-09-19 at 12:18:12, Peter Thorson wrote:
> A frame with the mask bit set and a mask key of 0 is still a masked 
> frame though is it not? Shouldn't the unmasked frames that the server 
> must reject per draft 15 be ones with the mask bit clear?

Given that there is no practical difference between the two, at least with respect to masking, I'd expect that a server would reject either in the same way.

---

From: John Tamplin <[email-masked]>
Date: Sun, 18 Sep 2011 23:51:48 -0400

On Sun, Sep 18, 2011 at 11:17 PM, Thomson, Martin <
[email-masked]> wrote:

> Given that there is no practical difference between the two, at least with
> respect to masking, I'd expect that a server would reject either in the same
> way.

Why?  The point of a random mask is that an attacker can't predict it.  He
can't predict a 0 mask any more than he can predict any other value.

Unless the protocol spec outlaws a mask of 0, any implementation that treats
a mask of 0 as equivalent to no mask is simply broken.  If the spec is
changed to outlaw it, then that means that an implementation has to check
for a random value of 0 and generate a new random value, and every
implementation has to check for a zero mask and fail the connection.  I do
not believe such a change is warranted, as the goal of masking is not to
prevent particular bit patterns on the wire but rather to prevent attacker
control of the bit patterns on the wire.

---

From: Willy Tarreau <[email-masked]>
Date: Mon, 19 Sep 2011 06:16:15 +0200

> control of the bit patterns on the wire.

And moreover, if we would reject zero, why not reject a number of other masks
as well, which in the end would reduce the randomness ? No, this is silly.
Masked frames are frames with the masked bit. The random has 1/2^32 chances
of being guessed. Each value we forbid reduces the randomness and makes the
code more complex on both sides for no added value.

Willy

---

From: "Thomson, Martin" <[email-masked]>
Date: Mon, 19 Sep 2011 14:02:37 +0800

On 2011-09-19 at 13:51:48, John Tamplin wrote:
> Why?  The point of a random mask is that an attacker can't predict it.
> He can't predict a 0 mask any more than he can predict any other value.

I can live with that.  It's a little bit of laziness that suits me fine.

On 2011-09-19 at 14:16:15, Willy Tarreau wrote:
> And moreover, if we would reject zero, why not reject a number of 
> other masks as well, which in the end would reduce the randomness ?

Um... because zero is the only number that is special in this way?

Before John's response, I'd have said that since a zero mask or no mask are equivalent.  A sanity check would have to reject either form if it was to catch lazy implementations that don't mask.

Of course, we can be intelligent about this and leave it to a server to detect naughty clients in their own way.  Maybe they will have to see a few 0 masked frames before they fail the connection.  That part is outside of specification.

--Martin

---

From: Willy Tarreau <[email-masked]>
Date: Mon, 19 Sep 2011 08:43:26 +0200

> Um... because zero is the only number that is special in this way?

It's not special at all. Use 0x47455420 as a mask and send a series of
zeroes. They'll appear on the wire as "GET ". This is similar. The only
goal of the masking is to prevent the client code from *choosing* the
bytes it sends over the wire, not to prevent it from accidentely sending
some patterns.

> Of course, we can be intelligent about this and leave it to a server to detect naughty clients in their own way.  Maybe they will have to see a few 0 masked frames before they fail the connection.…

I suspect that some simple non-browser implementations will probably use
0 at least during development to make debugging easier. As someone said,
browsers are the ones interested in masking, let's trust them to do it
right.

Regards,
Willy

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 19 Sep 2011 18:11:13 +1000

> Of course, we can be intelligent about this and leave it to a server to detect naughty clients in their own way.  Maybe they will have to see a few 0 masked frames before they fail the connection.…

Noooooooooooooooooooooooooooooooooooo

Please do not suggest the servers are responsible for detecting lazy
client implementations - either in the specification or in some kind
of defacto policeman mode.        This is the problem of the whole
masking concept, now that we have taken on the responsibility for
protecting the world from broken intermediaries, it is like we are
becoming some kind of self appointed Internet thought police.     It
is just not the servers responsibility to check the clients random
number generation for randomness or lazyness.

First the browsers have to protect us from broken intermediaries
Now the servers have to check that the clients really are protecting
us from the broken intermediaries?
Then will the client have to check that the servers are checking for
clients that really are protecting us from the broken intermediaries??

Can't we just trust the browsers to well implement and test their
implementations without involving deployed servers ?

regards

---

From: Brian McKelvey <[email-masked]>
Date: Mon, 19 Sep 2011 03:34:18 -0700

Yes, we can trust the browsers to get it right, and we must.  Any other response is absurd.  Further, it categorically does not matter in the grand scheme of things whether or not non-browser clients implement masking in the most secure possible way with strong PRNGs etc.

Trying to make servers "smart" and heuristically detect flaws in the clients masking will get us nothing but obscure bugs and interoperability nightmares.

Brian

Sent from my iPhone

---

From: Joe Mason <[email-masked]>
Date: Mon, 19 Sep 2011 11:20:22 -0400

Also, the point of the mask is to protect against safe clients running naughty code, talking to naughty servers.  So having a safe server validate the mask is useless because the safe server doesn't need the mask, and a naughty server will just skip the validation.

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On Behalf Of
> Greg Wilkins
> Sent: Monday, September 19, 2011 4:11 AM
> To: Thomson, Martin
> Cc: [email-masked]; Peter Thorson
> Subject: Re: [hybi] Rejecting client messages with mask=0 (X^0=X)
> 
> > Before John's response, I'd have said that since a zero mask or no
> mask are equivalent.  A sanity check would have to reject either form
> if it was to catch lazy implementations that don't mask.
> >
> > Of course, we can be intelligent about this and leave it to a server
> to detect naughty clients in their own way.  Maybe they will have to
> see a few 0 masked frames before they fail the connection.  That part
> is outside of specification.
> 

---------------------------------------------------------------------
This transmission (including any attachments) may contain confidential information, privileged material (including material protected by the solicitor-client or other applicable privileges), or constitute non-public information. Any use of this information by anyone other than the intended recipient is prohibited. If you have received this transmission in error, please immediately reply to the sender and delete this information from your system. Use, dissemination, distribution, or reproduction of this transmission by unintended recipients is not authorized and may be unlawful.