Subject: [hybi] A bit of pragmatism

From: Willy Tarreau <[email-masked]>
Date: Wed, 5 Jan 2011 10:57:27 +0100

Hi,

considering the amount of complexity we're trying to add to the protocol
to solve just a small part of hypothetical cases, I'm wondering why we
could not go with a pragmatic approach :

  - use the hello frames and swap the more/fin bits as suggested by
    Greg & Gabriel
  - add the "close" statement to the Connection header in the requests

With all that, for an intermediary to fail, it will be required that :
  - it does not understand status code 101 (around 1/50000 in Adam's tests
    if my memory serves me right)

  - it supports HTTP keep-alive

  - is able to find an HTTP request starting with a method composed of
    invalid chars (no such intermediary has been identified so far)

  - is able to accept a second request despite the "Connection: close"
    in the request (no such intermediary identified so far, though Greg
    admitted that this had been the case for an older server of his).

This might probably leave us with something between 0 and 1 in one million
possibly vulnerable intermediaries. Those if they even exist would be
particularly buggy considering that they have to fail on #3 above. Please
also note that #2 is already quite difficult to implement, which contradicts
the sloppiness of #3.

My question is : why should we bother for those ? We're making a mess with
the WebSocket protocol just because we suspect that there might exist some
stupid developers who probably quickly wrote something they called a proxy
in just an afternoon for their own use. If such products exist they surely
are not waiting for WebSocket to be exploited (eg: chunked encoding or
multiple content-lengths are even harder to get right than content-length).

So couldn't we focus on more-or-less HTTP-compliant implementations only,
cover a few implementation bugs and stop bothering about the most unlikely
scenarii involving deliberate bugs ? At one point, we should not try to
fix what people deliberately broke for their own use.

Best regards,
Willy

---

From: Salvatore Loreto <[email-masked]>
Date: Wed, 5 Jan 2011 11:48:44 +0100

Hi Willy,

thanks for your proposal,
but I would like folks to focus the discussion on the poll we are 
running at moment on Get+Upgrade+Masking
(btw the poll will over in two days: on January Friday 7th).

We are seeing a good consensus support for at least accepting (if not 
advocating) it:
of course there are still technical details that need to be defined and 
people are still discussing,
but the wheels are spinning.
For the chairs it is a great relief to see this much agreement.

Masking adds complexity to the protocol, that is true,
but the cost of masking is a reasonable price that we have to pay to 
security,
and a lot of people seem to be happy to compromise with it.

cheers
/Sal

-- 
Salvatore Loreto
www.sloreto.com

On 1/5/11 10:57 AM, Willy Tarreau wrote:
>      Greg&  Gabriel
> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi

---

From: Andy Green <[email-masked]>
Date: Wed, 05 Jan 2011 11:43:31 +0000

On 01/05/11 09:57, Somebody in the thread at some point said:

Hi -

> fix what people deliberately broke for their own use.

Couldn't agree more.

Security of these alleged intermediaries is out of scope for websockets 
because they remain as exploitable as they ever were for packets on both 
sides of them no matter what needless evasive action websockets takes.

Over-engineering websockets to death over a non-reproducible problem 
that websockets can't fix is crazy.

What's needed is to rule trying to solve the unsolveable out of scope 
and finish up any problems from the real world left with -03.

-Andy

---

From: Adam Barth <[email-masked]>
Date: Wed, 5 Jan 2011 11:26:24 -0800

On Wed, Jan 5, 2011 at 3:43 AM, Andy Green <[email-masked]> wrote:
> Over-engineering websockets to death over a non-reproducible problem that
> websockets can't fix is crazy.
>
> What's needed is to rule trying to solve the unsolveable out of scope and
> finish up any problems from the real world left with -03.

The security goals of browser vendors are higher than that.  As a
general rule, browser vendors do not kick the security can down the
road.  The buck stops here.

Adam

---

From: Andy Green <[email-masked]>
Date: Wed, 05 Jan 2011 19:47:58 +0000

> road.  The buck stops here.

The last couple of months appear to me to have been wasted with 
navelgazing trying to secure undefined broken intermediaries from attack 
by websockets, when websockets is not required to attack them.  In the 
meanwhile websockets are gone from Firefox by default exactly because 
the browser vendors don't want to be on the wrong side of security 
professionals finding they should have done something better and blaming 
them.

Actual security can be quite slippery and requires it to be well defined 
what it is that is trying to be secured from which attacks at what cost. 
  In this case, there is so much FUD about what the supposed problem is 
and what is needed to 'solve' it (again the problem is with the 
intermediary and cannot be solved by websockets; there is no definitive 
restestable problem scenario even) that the list appears to be reduced 
to a 'security jelly' talked into agreeing with the most forceful and 
aggressive-sounding proposals like AES munging.

In fact if the problem is real and misunderstood, and 'fixed' in the 
wrong place, that can be worse than useless.

 From what I read I didn't see any real outstanding problem that is 
websocket business that -03 and maybe the HELLO thing, and for sure 
wss:// don't already solve.

If you think that's incorrect, it should surely be possible to explain 
concisely what the problem is -- I mean really concisely -- and how it 
can be reproduced with normal, maintained and non-broken software in 
real use that makes it a websocket problem.

-Andy

---

From: Salvatore Loreto <[email-masked]>
Date: Wed, 5 Jan 2011 21:26:35 +0100

> that websockets can't fix is crazy.

here we are not talking of use WebSocket to fix the problems in the 
intermediaries,
but to design the protocol in a way that can not be used to generate 
attacks against another resource.

IETF encourages people

  "to consider security in their designs and to inform the reader of relevant security issues"

( http://www.ietf.org/rfc/rfc3552.txt )

/Sal

-- 
Salvatore Loreto
www.sloreto.com

---

From: Andy Green <[email-masked]>
Date: Wed, 05 Jan 2011 20:34:41 +0000

> attacks against another resource.

What exactly is the attack scenario that -03 is enabling?

What is being attacked, how can I reproduce it?  When I understood the 
mechanism, how can I satisfy myself that websockets was the right place 
to solve it when netcat and many other tools makes nice packets?

Because it seems to me we have been sat here doing the equivalent of 
fixing the PHP bug for them by disallowing the literal 
2.2250738585072011e-308 in websocket traffic, while inviting passers-by 
to "feel our security muscle".

-Andy

---

From: John Tamplin <[email-masked]>
Date: Wed, 5 Jan 2011 16:00:20 -0500

> mechanism, how can I satisfy myself that websockets was the right place to
> solve it when netcat and many other tools makes nice packets?

Because it seems to me we have been sat here doing the equivalent of fixing
> the PHP bug for them by disallowing the literal 2.2250738585072011e-308 in
> websocket traffic, while inviting passers-by to "feel our security muscle".

I'll try and summarize -- if in doubt, read the full paper Adam posted a
link to.

An attacker controls a server and JS code running in the client.  The JS
code establishes a WebSocket connection to that server that happens to pass
through a transparent HTTP proxy.  After establishing the connection, the
attacker sends WebSocket payload in each direction taking advantage of
proxies which do not understand WebSockets (or even GET+Upgrade) and think
the HTTP request is done when the server responds to the handshake, thus
interpreting further contents on the connection as HTTP requests/responses.
 The attacker can then make use of tricks to get the proxy to store
attacker-controlled data into its cache, which essentially creates an XSS
attack against every user behind that proxy (for example, consider getting
your contents returned for google.com/ga.js from the proxy).

The paper does not demonstrate an attack against the -03 protocol, but it
does raise enough questions about the possibility of such an attack that
Firefox and Opera deemed it prudent to disable WebSockets until this is
fixed.  It is difficult to give you exact reproduction mechanisms, since by
their nature transparent proxies are not directly visible and can not be
communicated with directly.  Since there are clearly some proxies which do
not understand GET+Upgrade to be changing the type of the connection, the
options are to not use it (CONNECT was suggested but there was substantial
objection), create roadblocks in the handshake or framing and hope they are
sufficient, or to prevent the attacker from controlling any payload bytes
from the client (no masking is needed on the server since the attacker is
already assumed to control it and can thus send anything it wants in
response, including non-WebSocket messages).  Option #1 seems unlikely to
gain consensus, #2 seems hard to reason about how safe it is (since for
example, such proxies might well skip garbage between HTTP messages), while
#3 seems provably secure at relatively low cost.  Hence, that is why we
appear to be close to achieving consensus on masking the client->server
frames.

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

---

From: Andy Green <[email-masked]>
Date: Wed, 05 Jan 2011 21:12:14 +0000

> connection, the attacker sends WebSocket payload in each direction
> taking advantage of proxies which do not understand WebSockets (or even
> GET+Upgrade) and think the HTTP request is done when the server responds

Understood.  But just like the PHP bug, what is the point of 'solving' 
this in websocket protocol?  The proxy is still sat there allegedly open 
to poisoning from similar-looking non-websocket packets, just like the 
PHP server is still sitting there waiting for something else to send it 
the constant of death.  Nothing is made "more secure" by having 
websockets in particular escape the equivalent of the PHP floating point 
constant.

In short, why is it a websocket problem when the attacker who controls 
the server can have it send other kinds of scripts that can open sockets 
and do the same attack?  The only solution is to close the hole in the 
proxy and fix the thing that is broken because it will otherwise remain 
broken and open to abuse no matter what websockets did.

> provably secure at relatively low cost.  Hence, that is why we appear to
> be close to achieving consensus on masking the client->server frames.

No, nothing got made "provably secure".  The proxy is allegedly still 
sat there waiting to be poisoned because it is supposedly still as 
broken as it ever was awaiting exploitation.  You can say, "that's not 
our problem" and you'd be right, none of it is a websocket issue 
including the proposed pointless munging action.  It's an alleged 
'broken exploitable proxy' issue.

-Andy

---

From: John Tamplin <[email-masked]>
Date: Wed, 5 Jan 2011 16:33:42 -0500

On Wed, Jan 5, 2011 at 4:12 PM, Andy Green <[email-masked]> wrote:

> Understood.  But just like the PHP bug, what is the point of 'solving' this
> in websocket protocol?  The proxy is still sat there allegedly open to
> poisoning from similar-looking non-websocket packets, just like the PHP
> server is still sitting there waiting for something else to send it the
> constant of death.  Nothing is made "more secure" by having websockets in
> particular escape the equivalent of the PHP floating point constant.
>

The browser does not currently allow arbitrary traffic in a non-HTTP
framing, which WebSockets does.  Sure, if you can convince a client to
download your code that does that and run it locally (which is essentially
how Flash/Java were also exploitable for this exact problem and why there
was a delay in releasing the details), then you can perform this (and many
other) attacks.  However, you don't do that by just browsing to a web site.

> In short, why is it a websocket problem when the attacker who controls the
> server can have it send other kinds of scripts that can open sockets and do
> the same attack?  The only solution is to close the hole in the proxy and
> fix the thing that is broken because it will otherwise remain broken and
> open to abuse no matter what websockets did.

If WebSockets were using HTTP framing throughout (such as chunked encoding
in both directions), then yes that would be the case -- but it isn't, which
means that WebSockets as of -03 opens new attack vectors that are not there
by other current means.

---

From: John Tamplin <[email-masked]>
Date: Wed, 5 Jan 2011 16:35:13 -0500

[sent too soon]

On Wed, Jan 5, 2011 at 4:12 PM, Andy Green <[email-masked]> wrote:

> No, nothing got made "provably secure".  The proxy is allegedly still sat
> there waiting to be poisoned because it is supposedly still as broken as it
> ever was awaiting exploitation.  You can say, "that's not our problem" and
> you'd be right, none of it is a websocket issue including the proposed
> pointless munging action.  It's an alleged 'broken exploitable proxy' issue.
>

If the attacker cannot control the bytes of the WebSocket payload, the
attacker cannot exploit it by including fake HTTP messages.

---

From: Adam Barth <[email-masked]>
Date: Wed, 5 Jan 2011 20:12:37 -0800

On Wed, Jan 5, 2011 at 11:47 AM, Andy Green <[email-masked]> wrote:
> The last couple of months appear to me to have been wasted with navelgazing
> trying to secure undefined broken intermediaries from attack by websockets,
> when websockets is not required to attack them.  In the meanwhile websockets
> are gone from Firefox by default exactly because the browser vendors don't
> want to be on the wrong side of security professionals finding they should
> have done something better and blaming them.
>
> what it is that is trying to be secured from which attacks at what cost.  In
> this case, there is so much FUD about what the supposed problem is and what
> is needed to 'solve' it (again the problem is with the intermediary and
> cannot be solved by websockets; there is no definitive restestable problem
> scenario even) that the list appears to be reduced to a 'security jelly'
> talked into agreeing with the most forceful and aggressive-sounding
> proposals like AES munging.

We know several approaches for fixing the problem.  The working group
has been discussing the trade-offs involved.  IMHO, the straw poll is
showing that there's generally broad support for Pat's proposal.

Adam

> In fact if the problem is real and misunderstood, and 'fixed' in the wrong
> place, that can be worse than useless.
>
> From what I read I didn't see any real outstanding problem that is websocket
> business that -03 and maybe the HELLO thing, and for sure wss:// don't
> already solve.
>
> concisely what the problem is -- I mean really concisely -- and how it can
> be reproduced with normal, maintained and non-broken software in real use
> that makes it a websocket problem.
>
> -Andy
>

---

From: Andy Green <[email-masked]>
Date: Thu, 06 Jan 2011 11:16:34 +0000

On 01/05/11 21:33, Somebody in the thread at some point said:
> On Wed, Jan 5, 2011 at 4:12 PM, Andy Green <[email-masked]
> <mailto:[email-masked]>> wrote:
>
>     Understood.  But just like the PHP bug, what is the point of
>     'solving' this in websocket protocol?  The proxy is still sat there
>     allegedly open to poisoning from similar-looking non-websocket
>     packets, just like the PHP server is still sitting there waiting for
>     something else to send it the constant of death.  Nothing is made
>     "more secure" by having websockets in particular escape the
>     equivalent of the PHP floating point constant.
>
>

It is not a raw socket though, it has handshaking to get it into that 
mode which is compatible with HTTP using upgrade.  The handshaking takes 
care to confirm that it is talking to a partner that understands 
websocket framing and is willing to talk it using that.  It is not at 
all like websockets is the new LOIC.  There is a vanishingly narrow 
story for things that can be attacked, broken intermediaries that don't 
understand upgrade and stay in HTTP mode.  And if they exist, they can 
be fixed.

> download your code that does that and run it locally (which is
> essentially how Flash/Java were also exploitable for this exact problem

I take your point about the one-stop-shop if there are things that do 
bad things seeing websocket protocol.

But nobody has shown one of these supposed buggy intermediaries or 
describe how to reproduce a failure involving one.  AFAIK because the 
failure mode is just inferred, nobody has confirmed that whatever was 
done to Flash and Java in the name of "security" closed any actual holes.

Maybe some intermediaries are buggy and never saw a websocket handshake 
until now... that state of affairs won't continue if websockets is a 
success.

> If WebSockets were using HTTP framing throughout (such as chunked
> encoding in both directions), then yes that would be the case -- but it
> isn't, which means that WebSockets as of -03 opens new attack vectors
> that are not there by other current means.

It uses upgrade which should be enough if the intermediary is complaint. 
  And if it's not compliant and does bad things when sent upgrade and 
other packets, that is not going to be solved by eliminating one source 
of upgrade and other packets.

 From the other mail ->

 >> No, nothing got made "provably secure".  The proxy is allegedly
 >> still sat there waiting to be poisoned because it is supposedly still
 >> as broken as it ever was awaiting exploitation.  You can say, "that's
 >> not our problem" and you'd be right, none of it is a websocket issue

 > If the attacker cannot control the bytes of the WebSocket payload,
 > the attacker cannot exploit it by including fake HTTP messages.

What do you think got made "provably secure" and against what? 
Websockets protocol itself is made no more secure against eavesdropping 
by addition of AES munging that has the keys on the wire.  The handshake 
scheme seems secure enough already against accidentally talking to a 
partner that won't be able to talk websockets properly; payload munging 
won't add to that.

What you mean is that you think it will be 'proven' that an undefined 
intermediary that doesn't understand websockets will act securely when 
we spam gigabytes of /dev/random-ish 8-bit data with what you previously 
called "non HTTP framing" (despite Upgrade) at it.

Because we accept to shadow-box with supposedly broken-but-unknown and 
unfixable intermediaries that can have any response to anything and that 
is meant to be a websocket problem, in fact you can't prove anything 
about a system involving such an unknowable black box.  As soon as you 
accept the unknown broken-ness of the supposed intermediary being a 
websocket problem you are just reliant on agreement with the people 
playing 'broken intermediary devil's advocate' when they feel like it or 
tire of the game.  That's not proving anything.

 From what I can see, including the bad-tempered Opera thread, 
websockets is out by default now as much from exhaustion with tracking a 
spec that isn't converging as intermediary FUD: I don't know why else 
wss:// is pulled along with ws://.  Actually -03 is a really nice spec 
already if we stop trying to solve the unsolveable as well.

-Andy

---

From: Andy Green <[email-masked]>
Date: Thu, 06 Jan 2011 11:20:56 +0000

> showing that there's generally broad support for Pat's proposal.

What exactly do you mean, "fix the problem"?  The "problem" is 
ultimately a supposedly broken intermediary, right?  NOTHING is going to 
FIX the supposed vulnerability that creates except fixing the 
intermediary itself.

Everything else, any amount of "working group discussion", is just 
leaving the thing wide open to attack from any other direction, but not 
websockets, no sir.

-Andy

---

From: Dave Cridland <[email-masked]>
Date: Thu, 06 Jan 2011 12:55:55 +0000

On Thu Jan  6 11:16:34 2011, Andy Green wrote:
> describe how to reproduce a failure involving one.  AFAIK because  
> the failure mode is just inferred, nobody has confirmed that  
> whatever was done to Flash and Java in the name of "security"  
> closed any actual holes.

No, it was demonstrated that a strong potential exists, modulo the  
effects of framing (which are pretty unpredictable). It was also  
shown that all affected intermediaries ceased to be viable as an  
attack surface given a CONNECT.

The entire discussion on masking is a red herring, given the  
experimental data suggests that 50,000 random beds were looked under,  
and no monsters were found.

You statement above, in any case, simply implies that as long as  
WebSockets prevent the vast majority of attacks (easy - include  
something that looks like a CONNECT at some point in the flow), then  
any would-be attacker will move onto Java and Flash instead, and - if  
we want to make the obvious cynical observation - either drive  
websocket adoption or encourage intermediaries to be fixed.

Dave.
-- 
Dave Cridland - mailto:[email-masked] - xmpp:[email-masked]
  - acap://acap.dave.cridland.net/byowner/user/dwd/bookmarks/
  - http://dave.cridland.net/
Infotrope Polymer - ACAP, IMAP, ESMTP, and Lemonade

---

From: Andy Green <[email-masked]>
Date: Thu, 06 Jan 2011 13:14:27 +0000

On 01/06/11 12:55, Somebody in the thread at some point said:
> effects of framing (which are pretty unpredictable). It was also shown
> that all affected intermediaries ceased to be viable as an attack
> surface given a CONNECT.

If I understood it, the presence of vulnerable intermediaries was 
inferred by a client script doing something or not.  Because it was done 
via advertising and not under repeatable conditions that are open to 
analysis, the reason the script may have appeared to stop doing 
something is open to interpretation since the whole stack between the 
client and attack sensor is unknown, uncontrolled and unrepeatable.

That's why I asked yesterday --> "If you think that's incorrect, it 
should surely be possible to explain concisely what the problem is -- I 
mean really concisely -- and how it can be reproduced with normal, 
maintained and non-broken software in real use that makes it a websocket 
problem."

> something that looks like a CONNECT at some point in the flow), then any
> would-be attacker will move onto Java and Flash instead, and - if we
> want to make the obvious cynical observation - either drive websocket
> adoption or encourage intermediaries to be fixed.

To be clear websocket masking does nothing to fix the allegedly broken 
and vulnerable intermediary which remains listening on a socket and 
willing to do whatever it does if you feed it the right packets by any 
means.  The only way to fix that is identify and fix the broken 
intermediary that is alleged to exist, not bend every client out of 
shape just in case.

Completely agree that masking websockets is needless.  Even if an actual 
broken intermediary is identified with this behaviour, that just leads 
to the thing being fixed and masking is still doing nothing.

-Andy

---

From: Dave Cridland <[email-masked]>
Date: Thu, 06 Jan 2011 13:59:56 +0000

On Thu Jan  6 13:14:27 2011, Andy Green wrote:
>>> the
>> shown
> inferred by a client script doing something or not.  Because it was  
> done via advertising and not under repeatable conditions that are  
> open to analysis, the reason the script may have appeared to stop  
> doing something is open to interpretation since the whole stack  
> between the client and attack sensor is unknown, uncontrolled and  
> unrepeatable.
> 
> 
I think that's an unhelpful stance. The general description of the  
experiment conducted is sufficient to repeat it, but by its nature it  
selected a largely random set of intermediaries. That's enough to  
satisfy me that it's essentially valid.

> should surely be possible to explain concisely what the problem is  
> -- I mean really concisely -- and how it can be reproduced with  
> normal, maintained and non-broken software in real use that makes  
> it a websocket problem."
> 
> 
Streams of data that *look* like HTTP requests sent *after* a  
supposedly successful Websocket handshake (of the Upgrade type) are  
known to be interpreted as HTTP requests on some intermediaries. This  
leads to one of three problems:

a) An attacker can access data within the firewall.

b) An attacker can poison the intermediary's cache for third-party  
URIs, leading to the potential case where the Google Analytics  
script, for example, is poisoned to include script code of the  
attacker's choice.

c) The intermediary fails to pass websocket data flows.

However, neither (a) nor (b) was found when CONNECT was used as the  
sole handshake. (CONNECT has other problems, such as removing  
semantic transparency of intermediaries, but that's why I suggested  
using it following an Upgrade). Even occurances of (c) were found to  
be miniscule.

> Completely agree that masking websockets is needless.  Even if an  
> actual broken intermediary is identified with this behaviour, that  
> just leads to the thing being fixed and masking is still doing  
> nothing.

Right. And I should point out that the paper that first proposed  
masking also describes an experiment that found it to be worthless  
given certain precautions. Given the facts, I'm at a loss as to why  
this particular bandwagon has been so thoroughly jumped upon.

Dave.

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 6 Jan 2011 15:41:51 +0100

On Thu, Jan 06, 2011 at 01:59:56PM +0000, Dave Cridland wrote:
> known to be interpreted as HTTP requests on some intermediaries.

We only know that in the case where the stream corresponds to a 100%
valid HTTP request. I don't believe a minute that such intermediaries
will skip all bytes and magically resync on the ones that look like a
known method to them. As Bjoern suggested it, we could think about the
laziest implementation. A lazy implementation would very possibly
consider the stream as the method till the next space. That will not
make this method eligible for caching though. Please note that I find
your method consisting in emitting a CONNECT efficient against this
type of failure.

Anyway, now we're going to have masking on by default. Once again, I
think it's not a big trouble for browser->server communications, but
as some people have raised it here, browsers are not the only HTTP
clients, so there is no reason they are the only WebSocket clients.

Look at the success of WebServices. They rely on HTTP just like us
and they're used between servers. I think that clean WebSocket
implementations could very well replace ICAP or simple transaction
based protocols which exchange very few data. In all of these
situations, masking has a cost and offers no benefit.

That's why I'm re-iterating that we should consider the option of
disabling masking, but not for browsers. The sole reason we proposed
masking is because we suspect that some broken and uncontrolled
intermediaries on the net might be vulnerable, and that browsers
could become a nice vector to attack them.

Within internal networks, there is no such issue and that's where
we'd like to save useful CPU cycles and bytes on the wire, so
disabling masking there would really make sense. That would also
satisfy the needs of those who want to implement border WS gateways
which will decode the stream and pass it unencoded to next servers
(think about smart load balancers for instance).

We're complying with a well-established protocol. We should use the
workarounds only when we fear the underlying protocol might not be
reliable. But if it is, we should not have to fall back to workarounds.

Regards,
Willy

---

From: Andy Green <[email-masked]>
Date: Thu, 06 Jan 2011 14:56:42 +0000

On 01/06/11 13:59, Somebody in the thread at some point said:
>> done via advertising and not under repeatable conditions that are open
>> to analysis, the reason the script may have appeared to stop doing

There is no evidence at the end of the claims made, no proxy we can look 
at exhibiting the behaviour and confirm the mechanism, no way to verify 
that it is fixed or worked around.  No way to even zero in on the 
network or proxy that they claim showed the behaviour.  There's no way 
to close the circle between the observed results and the claimed 
interpretation of them considering the implementation and the 
uncontrolled test networks.

For example, we might expect to see a POC trashing a particular build of 
a particular proxy using -76 that is out there.  Such an issue can be 
reproduced, verified, understood, resolved (by updating that proxy), closed.

It seems to me that it is quite hard to distinguish the claims in the 
paper from pure FUD considering the above.

>> should surely be possible to explain concisely what the problem is --
>> I mean really concisely -- and how it can be reproduced with normal,
>> maintained and non-broken software in real use that makes it a
>> websocket problem."
>>
> Streams of data that *look* like HTTP requests sent *after* a supposedly
> successful Websocket handshake (of the Upgrade type) are known to be
> interpreted as HTTP requests on some intermediaries. This leads to one
> of three problems:

Yeah I read the same.  I'm still waiting to hear how do I reproduce that 
"with normal, maintained and non-broken software in real use that makes 
it a websocket problem."  When I do hear the exact software that is 
broken, it becomes a "fix and update your broken proxy" problem with a 
specific vendor, nothing to do with websockets.  We only feel it may be 
a websocket problem because of this perfect lack of information about 
what this broken intermediary is and the details how it acts.

-Andy

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 6 Jan 2011 17:36:47 +0100

So we have one camp that strongly believes that vulnerable
intermediaries are our concern and that masking is a credible defence.
We have another camp that strongly believes that vulnerable
intermediaries, if they exist, are not our concerns and masking is a
waste of time. We have a smattering of opinions in between.

So we can keep going hammer and tong at each other trying to break
down the strongly held views of the other camp....  OR we can find a
compromise.

Both camps need to accept that the concerns of the other camp are at
least valid for them - even if they are dubious if they are real
technical concerns or just political/stylistic concerns.  Telling
somebody: "these are not the concerns you should be worried about" is
not very helpful (unless the concerns are about droids and you are
obe-wan kenobi).

So I think we all have to accept that some want masking and some
don't.   So surely given this divide, making masking an extension is
the reasonable and pragmatic way forward.   The browser vendors who
appear most concerned about this issue can make the extension
mandatory, those that don't want masking in their particular
deployment can opt out (so long as they are not using browser).

The arguments against masking as an extension are:

 + it could be turned off.  Well then don't implement it as an
optional extension! don't allow it to be turned off in vulnerable
deployments.
 + extension mechanism is not up to the task.  Well we'd better fix it
then, because masking is not that complex and if we can't handle that
we have problems.
 + There may be some attacks that apply to servers from non-WS clients
which can have masking turned off.  Well if that ever becomes a
problem, then those servers can also make the masking extension
mandatory.
 + Complexity of negotiating the extension.  Then make it a default
extension and you have to negotiate not to have it.

It was really great to see some progress towards consensus around
Upgrade+Masking.   It would be a great pity to see that stalled
because of either insistence on a specific style of masking or refusal
to accept that some really want to have masking.

regards

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 6 Jan 2011 19:46:07 +0100

Hi Greg,

On Thu, Jan 06, 2011 at 05:36:47PM +0100, Greg Wilkins wrote:
> the reasonable and pragmatic way forward.

That's pretty much the point I was making as my first response to Sal'
poll : have the masking mandatory for browsers but ensure that it's
easy to make the protocol work without it so that implementations that
don't need/want it can get rid of it.

> The browser vendors who

In my opinion it should work this way :
  - client sends handshake to server
  - server may announce in the first hello frame its masking capabilities
    and its intent to work with/without masking
  - browsers just have to refuse the non-masking mode
  - other clients can safely adapt to the server's capabilities

That may even make it possible to support AES-CTR or anything else if some
users find it more suited for their task.

> extension and you have to negotiate not to have it.

I agree with the points above.

> to accept that some really want to have masking.

Once again, I agree with the principle of masking provided it's optional.
What annoys me is that every time some progress is made, some unneeded
complexity is added somewhere (eg: HMAC to get a random key for each
block). All this complexity piling up comes at a substantial cost for
those who are not subject at all to the risks it is meant to address.

And I'm still thinking about the ability to build WS accelerators,
which would simply decode the traffic on the entry point, and use
multiplexing to forward it to a bunch of servers. Those severs will
have no use of the encoding at all, all they'll want is a low number
of threads, file descriptors, and CPU usage. It would be a pity if
the front accelerator has to compute an HMAC for every few characters
forwarded from a client to a server...

Regards,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 6 Jan 2011 10:52:17 -0800

On Thu, Jan 6, 2011 at 10:46 AM, Willy Tarreau <[email-masked]> wrote:

> block).

I don't recall anyone suggesting that. Certainly, it's not necessary. What's
necessary
is that the CTR IV for each block be random. Can you point to the message
where
someone suggested that?

-Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 6 Jan 2011 23:14:26 +0100

> is that the CTR IV for each block be random. Can you point to the message

It was yourself as a response to John :-) right here :

   http://www.ietf.org/mail-archive/web/hybi/current/msg05425.html

He was suggesting :
   "...
    To send a frame, the client performs the following steps:
    - chooses a random per-frame-key (size TBD based on brute force
      attacks against the key, but likely 4-8 bytes)
    - computes the 20-byte SHA1 of the string "WebSocket", server-nonce,
      client-nonce, per-frame-key (in that order)
    - send the per-frame-key
    - XORs each byte in the frame, including headers and after compression
      if any, with successive bytes of the SHA1 hash and sends them
    ..."

and you replied :

   "A few comments as token crypto-oriented guy:
    (1) I'd prefer a UUID to the WebSocket string.
    (2) I'd prefer HMAC to SHA-1..."

Regards,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 6 Jan 2011 15:37:26 -0800

My bad, I misunderstood the context:

1. Yes, I think you should generate completely fresh keystream for each
record.
2. We had originally talked about using AES-CTR for this, but it's possible
that for
export reasons people might prefer HMAC-SHA1.

This isn't some piece of new complexity: it's been part of the proposed
masking
since the very beginning. The only difference is that HMAC-SHA1 is being
suggested as
an AES-CTR replacement. I realize that you don't think this is necessary,
and I guess
I might be willing to live with a simpler mechanism, but it's not, as you
suggest, something
that just appeared when we were starting to make progress.

-Ekr

---

From: Bruce Atherton <[email-masked]>
Date: Thu, 06 Jan 2011 16:16:15 -0800

> not very helpful (unless the concerns are about droids and you are

This is a really important point. The reality is that just because 
something is not your fault does not mean it is not your problem. I'm 
sure we have all experienced situations where that is true. For browser 
developers, just having the browser involved in an attack results in 
fingers being pointed at them. Masking gives them a simple story to tell 
about how to prevent a large number of potential attacks and will let 
them sleep better at night knowing it is less likely that they will have 
to pull all-nighters to work around some bizarre hack that isn't even 
their fault. Why not let them have it?

Besides, supporting mandatory masking in browsers will be beneficial 
even to those who don't see the need because it will make future 
decisions concerning the protocol much easier to make. By limiting 
attacker control of bits on the wire to just a URL, all kinds of debate 
about the impact of a change to the Websocket protocol becomes 
simplified. Just look at how it simplified the GET+Upgrade vs. CONNECT 
debate.

As I've said before, even if you don't personally understand why a group 
on this list wants something, you should trust them enough to allow that 
they probably have a good reason for wanting it.

> extension and you have to negotiate not to have it.

I think this point nicely deals with the asymmetric nature of the 
client/server behaviour I have an issue with. Imagine if the spec 
indicates that browsers will only send masked data but will accept 
either masked or unmasked data back from the server. Then simple servers 
that didn't fully implement extensions would just mask by default, and 
those that wanted to efficiently sendfile() or turn off masking in a 
trusted environment would have to deal with the added complexity of 
implementing the "nomask" extension, as would clients or peers that 
wanted no masking.

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 06:34:10 +0100

On Thu, Jan 06, 2011 at 03:37:26PM -0800, Eric Rescorla wrote:
> that for export reasons people might prefer HMAC-SHA1.

OK, I get it now.

> that just appeared when we were starting to make progress.

OK. My concern is that it comes with a cost. I know a large site who is
dealing with hundreds of thousands of concurrent chat connections. They're
dealing with very small messages, a few bytes of payload at a time at best.
You can certainly imagine the load on the servers if they have to compute
an HMAC every two-three character typed on the keyboard!

I understood your point with the random keys as a way to prevent the server
from making the client emit predictable data. In my opinion, if the client
generates the random key on its side without depending on anything and simply
announces it, we can achieve the same result. We can *suggest* methods to help
the client generate a random when it does not know how to do so, but I don't
see a reason why it should depend on multiple parameters.

Also the key does not need to be larger than the number of bytes to encode
a frame length (7, 16, 63 bits), because what's important is that a message
cannot span the entire keyspace. In theory, a simple 8-bit random could be
enough for a message with a payload shorter than 128 bytes. However, having
a variable length mask would only work if it's sent in the extension field,
but that's probably something to think about.

I would very well see something like this for the client :
  - generate a random of 8, 16 or 64 bits depending on the payload
    length. The larger ones should be strong enough and may involve
    hashing to avoid predictability.

  - announce the random in the extension data

  - XOR the application data with that random

We could even make use of the RSV4 bit to indicate that the frame is encoded.
It will result in all easily controllable bytes before the key to have the
high bit set and would make it easy for the other side to decode the frames,
because by design the key would be the same size as the payload length field.

Regards,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 6 Jan 2011 21:47:30 -0800

> an HMAC every two-three character typed on the keyboard!

Really? That's not the behavior I'm familar of with chat systems, where
things
are generally phrased in stanzas that are > 20 bytes longs. This is true of
XMPP, for instance. What systems are you thinking of?

That said, even if you have such a system, I'm not at particularly concerned
about the
load being prohibitive. Symmetric encryption is very fast (see Langley and
Modadugu's
velocity talk for reference on this).

> cannot span the entire keyspace.

I don't know where you're getting this analysis, but it doesn't sound
correct
to me. The probability of guessing a valid key is 2^{-key size}. The liit
you're talking about only applies if you want to be guaranteed you have
a valid plaintext within a single frame.

Even if you have a much larger mask, if you simply repeat it, there will be
correlations with the mark when it repeats. I'm not aware of any attack on
this,
but it's also not demonstrably safe, whereas the technique I described is.

-Ekr

---

From: "Thomson, Martin" <[email-masked]>
Date: Fri, 7 Jan 2011 13:48:27 +0800

>     length. 

I don't think that this logic works.  The reason for having more randomness is to reduce the probability that the server is able to guess the random value.  You have less randomness because you want to save bytes.  

This is not about reducing the probability of the client emitting data that could be misunderstood - that is a function of the length of the message, independent of the amount of randomness you are providing.  Adding more randomness doesn't reduce the chance of a message containing "GET / HTTP/1.1" or any other such potentially dangerous stuff, you can only do that by sending less data.

>     The larger ones should be strong enough and may involve

You want a secure random number generator if your goal is to avoid someone predicting the outcome see [RFC4086].
 
>   - XOR the application data with that random

That would be sufficient, just decide how much randomness is sufficient.  A fixed value should be sufficient, and we should be able to come up with a probability we can all agree on.

--Martin

---

From: "Thomson, Martin" <[email-masked]>
Date: Fri, 7 Jan 2011 13:55:29 +0800

On 2011-01-07 at 16:47:30, Eric Rescorla wrote:
> correlations with the mark when it repeats. I'm not aware of any attack
> on this,

Depends on what you are trying to prevent.  As I understand it, you are trying to prevent untrusted code from being able to directly control what is on the wire.  Repeating the mask is still sufficient: 2^-k probability.  It's not like the server isn't going to have the value.

We have to assume that once the server starts receiving a frame it can tell the untrusted code what the mask is.  AES-CTR and HMAC both only increase the cost of prediction at that point.  You have to prevent the server from being able to close the loop by making sure that you have all the data for a frame before you start sending.

--Martin

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 6 Jan 2011 21:59:56 -0800

On Thu, Jan 6, 2011 at 9:55 PM, Thomson, Martin
<[email-masked]>wrote:

> Depends on what you are trying to prevent.  As I understand it, you are
> trying to prevent untrusted code from being able to directly control what is
> on the wire.  Repeating the mask is still sufficient: 2^-k probability.
>  It's not like the server isn't going to have the value.

With a repeating mask, the attacker can (for instance) ensure that byte i is
the same
as byte i+masklen, regardless of the mask value. As I said, I don't know how
to exploit
this, but I also have yet to see a demonstration that it's not exploitable.

 -Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 07:01:28 +0100

> I don't think that this logic works.  The reason for having more randomness is to reduce the probability that the server is able to guess the random value.  You have less randomness because you wan…

No, the randomness I'm talking about is to reduce the probability that the
server will guess the key and exploit it. If the key is changed for each
frame, the ability for the server to guess *and exploit* it depends on the
message length too. The server does not have more chance to forge a correct
message when it has 1/256 change to guess the key on a message that's 256
bytes long than when it has 1/65536 on a message that's 65536 bytes long.

That said, we could probably have the minimum random size something like
32 bits for small payloads, it's not a big deal if the masking is optional.

Regards,
Willy

---

From: "Thomson, Martin" <[email-masked]>
Date: Fri, 7 Jan 2011 14:04:27 +0800

On 2011-01-07 at 16:59:56, Eric Rescorla wrote:
> With a repeating mask, the attacker can (for instance) ensure that byte
> i is the same
> as byte i+masklen, regardless of the mask value. As I said, I don't
> know
> how to exploit

I'll concede that.  I'm not aware of any protocol that relies on relative values of bits/bytes as opposed to absolute values, but there's always room for surprises.

---

From: "Thomson, Martin" <[email-masked]>
Date: Fri, 7 Jan 2011 14:08:39 +0800

> bytes long than when it has 1/65536 on a message that's 65536 bytes

You need more space to exploit it, sure.

But since we were talking about pragmatism, we have to expect that the probability of an intermediary ignoring noise decreases as the amount of noise increases.  You could almost say that the first bytes are going to be the most crucial.  But that doesn't help if we're heading for an ironclad, provable probability.

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 07:10:43 +0100

> XMPP, for instance. What systems are you thinking of?

I was thinking about the short messages typed on the keyboard such as "lol"
and smileys. But even if your stats indicate an average of 20 bytes, we're
still smaller than the average IP+TCP header and we have to deal with one
different message every few bytes of payload. That was my point.

> velocity talk for reference on this).

Well, at 1 million concurrent connections with a 5s think time, that's about
200k frames per second, it starts to be concerning even if it's cheap.

> a valid plaintext within a single frame.

That's my point. Otherwise the server has to make the client send on average
2^{key size} random messages to get what it's looking for. I agree I was wrong
on one point, I assumed it meant that full-sized messages would have to be
sent while this is not the case. We could make the client send lots of short
messages get a valid one.

But even a 32-bit minimum key size for small frames would seem far enough,
don't you think ?

> correlations with the mark when it repeats.

That's why I wanted to use larger masks for larger frames, in order to avoid
those repetitions.

> I'm not aware of any attack on
> this,

Regards,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 6 Jan 2011 22:16:55 -0800

> different message every few bytes of payload. That was my point.

Yes, and the performance will be comparable to TLS.

> 200k frames per second, it starts to be concerning even if it's cheap.

My dinky Macbook Air does one million SHA-1 ops/second on a single core.

Again, see the Modadugu and Langley talk for real performance numbers.

> 2^{key size} random messages to get what it's looking for.

So? I have no idea why you think this is acceptable.

> don't you think ?

No.

-Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 07:38:54 +0100

> My dinky Macbook Air does one million SHA-1 ops/second on a single core.

That means a 20% CPU overhead imposed by masking then.

> Again, see the Modadugu and Langley talk for real performance numbers.

OK, will take a look.

> But even a 32-bit minimum key size for small frames would seem far enough,

Then I don't follow you. If the server has to send on average 2^32
messages to have a chance to see "\nGET /\n", that's 28 GB of upstream
traffic, or 52 GB with the framing and key. The client needs to be able
to send it unnoticed by the user (52GB over ADSL...) and we must expect
the broken intermediary to parse all that random crap without blinking
an eye and suddenly spot our precious request. It will likely have
spotted other ones as well before it BTW.

That's why I was talking about pragmatism. We're trying to avoid
some broken intermediaries to spot a valid request in the stream
following the handshake and we consider that 52GB of random crap
after the handshake it still represents a risk, and that's where
I disagree :-/

Willy

---

From: Greg Wilkins <[email-masked]>
Date: Fri, 7 Jan 2011 09:42:21 +0100

I really don't understand why we need to specify the algorithm to
compute the masking key.

Can't we just say that when masking is on, every frame has a random 32
byte mask which is applied with XOR to the payload.  We can leave it
to the client to generate the random mask with whatever algorithm
using whatever salt that it likes. In fact, if we don't specify an
algorithm, then there will be more natural variation in algorithms
used and no systematic issues that will effect all clients.

---

From: Andy Green <[email-masked]>
Date: Fri, 07 Jan 2011 08:42:52 +0000

> some broken intermediaries to spot a valid request in the stream

If it really is the goal of websocket protocol is to disable any 
possible undefined attack on any possible undefined broken intermediary, 
broken in any possible combination of undefined ways, sure 32 bit key 
isn't enough; nothing's gonna be enough.

How about some agreement first on what attacks it is that the crypto 
voodoo is trying to disable, and what it doesn't care about.

For example, some arbitrarily broken intermediary may blow up if you 
send it an 0xff, we can all agree that's too broken to care about saving.

There's some doubt that any real intermediary will sit through gigabytes 
of junk and then match on GET in the middle of it.  Maybe we can agree 
that also would be an intermediary that is not worth the effort to protect.

Are there any other cases we can agree are beyond saving and need not be 
considered?

How many cases are disabled from attack if the websocket framing began 
always with the constant "\x0d\x0a\x0d\x0a", so you could never 
subsequently send data that could be interpreted as http headers or request?

-Andy

---

From: Dave Cridland <[email-masked]>
Date: Fri, 07 Jan 2011 09:16:23 +0000

On Fri Jan  7 08:42:52 2011, Andy Green wrote:
> How many cases are disabled from attack if the websocket framing  
> began always with the constant "\x0d\x0a\x0d\x0a", so you could  
> never subsequently send data that could be interpreted as http  
> headers or request?

We don't know, and can't tell without experiment.

We can, however, say that we know due to such an experiment that no  
intermediaries are known to exist which interpret data in a dangerous  
way subsequent to a CONNECT - although this has only been tested as  
the first method used in a stream, to be precise. This implies that  
either of the original CONNECT-based handshake proposed, and my  
subsequent standards-conformant adaptation that (apparently) nobody  
likes, would be sufficient to reduce attacks to a percentage of  
intermediaries sufficiently small that none have been found to date.  
One may as well say that these intermediaries don't exist, and claim  
that proof because the invisible pink unicorn told us so, because  
it'll be just as easy to prove the non-existence of the IPU as to  
prove the non-existence of the intermediaries, and frankly as valid,  
given that experimental data at least supports the unicorn's  
statement.

However, it seems that a very strong reality distortion field is in  
place in this working group - mere facts and experimental data are  
insufficient, and to be cast aside if they don't fit the theory, and  
we seem to have rechartered ourselves into a working group hell-bent  
on preventing any buggy third-party from being used as an attack  
surface in this or any possible parallel universe, past, present, or  
future. So we seem to be lumbering ourselves with some truly  
impressive baggage that future developers will either look upon  
aghast, or with amazement that we somehow predicted a sudden and  
uncharacteristic rise in vulnerable intermediaries - possibly even to  
measurable levels - despite all reasonable expectation to the  
contrary.

I'm personally expecting the former - masking will become less and  
less relevant (and this is taking the generous step of assuming it  
has any relevance today), and we will be hamstrung with a protocol  
forcing us to mask every byte on the network for no reason whatsoever.

Please, get off this bandwagon. The original paper which proposed  
masking as a side note also had an experimentally tested solution.  
Let's base our solution on that, and not go dashing off into  
theoretical weeds.

Dave.

---

From: Greg Wilkins <[email-masked]>
Date: Fri, 7 Jan 2011 10:35:39 +0100

On 7 January 2011 09:42, Andy Green <[email-masked]> wrote:
> always with the constant "\x0d\x0a\x0d\x0a", so you could never subsequently
> send data that could be interpreted as http headers or request?

Andy,

I think masking has been proposed as a way to get around the
unprovables about the safety or otherwise of prefixes.

There appears to be some who think a prefix of "CONNECT something
HTTP/1.1\r\n\r\n" to a stream is sufficient protection. Yet there are
also counter opinions that having a Hello frame at the start of the
stream and every frame starting with a byte with the high bit set is
insufficient. We iterated for a month or so trying to nail down
exactly what was sufficient or insufficient and got no where.

Masking appears the most popular solution because it avoids the need
to decide what is sufficient or not - or so  I thought. But now we are
getting bogged arguing about if the masking algorithm is sufficiently
strong or not.   We are fighting over meta meta concerns!

I'd like to propose the following:

 + The specification is updated so that extensions can use extension
data with out using a reserved bit
 + A "masking" extension is defined that includes a 32bit masking key
in the extension data of each frame.   The key should be
unpredictable, but the specification will not define how it is
generated.
+ The masking key is applied with XOR to all extension data following the key.
+ The masking key is applied with XOR to all normal payload.
+ The masking extension is the default extension, so that if no
extensions are negotiated it will be used from client->server
+ If other extensions are negotiated, then "masking" will need to be
explicitly negotiated in the list of extensions.
+ We also define the "identity" extension, which is a do nothing
extension.  If both ends negotiate to use the "identity" extension
only, then only the do nothing extension is applied and masking is not
used.
+ Browsers or any client that executes 3rd party code, MUST NOT accept
connections with identity only extension.

While I'm sure you all have better proposals that this, the problem is
everybody has different better proposals.
So my question is would such a proposal be a show stopper for anybody?

regards

---

From: Andy Green <[email-masked]>
Date: Fri, 07 Jan 2011 09:42:38 +0000

> We don't know, and can't tell without experiment.

I take your point but actually if we first agreed exactly what possible 
vulnerabilities we cared about, and they were few in number and 
well-defined, it would be possible to determine that one workaround or 
another would definitively disable possibility of those attacks without 
experiment.

Experiment would tell us if any intermediaries could actually be found 
in the field with that vulnerability, but the corner we are backed into 
now with websockets disabled in two main browsers because of "security", 
reality is no longer the issue if it ever was.  The issue now is finding 
a way to save face for them so they can re-enable websockets in their 
browser consistent with having shut it off over claims that have not yet 
delivered a broken piece of intermediary software for us to poke at and fix.

> way subsequent to a CONNECT - although this has only been tested as the

Did you identify what that intermediary is with that behaviour, or find 
a way to make the problem repeatable for others?  It's one thing to say 
n% of a random and unrepeatable test did this or that it's much more 
effective to announce "squid 3.1.9 in transparent breaks on websocket 
without CONNECT"... that will lead to reproduction, and squid getting 
fixed and solving it that way without websockets needing to do anything.

> insufficient, and to be cast aside if they don't fit the theory, and we
> seem to have rechartered ourselves into a working group hell-bent on
> preventing any buggy third-party from being used as an attack surface in
> this or any possible parallel universe, past, present, or future. So we

lol Completely agree

> masking as a side note also had an experimentally tested solution. Let's
> base our solution on that, and not go dashing off into theoretical weeds.

Munging payload makes no sense to me in case you got the idea I am on 
that bandwagon.

If CONNECT or some CRLFs in the framing allow the browsers to re-enable 
websockets without munging, so we can go on, that's a price worth paying 
IMO (even though I think all of it is pointless and a problem to be 
solved at the intermediary only).

-Andy

---

From: Andy Green <[email-masked]>
Date: Fri, 07 Jan 2011 09:59:23 +0000

> exactly what was sufficient or insufficient and got no where.

It's because there is no central definition of which intermediary 
attacks we are trying to disable.  Each person is making his case for a 
solution with his private ideas of what the goal is.

> strong or not.   We are fighting over meta meta concerns!

Yeah, masking seems to people to be the strongest possible medicine for 
disabling attacks, so in the vacuum of any definition of what they are 
trying to achieve with it, people who think something should be achieved 
gravitate towards that.  But like I said, actually with the goal of 
having masking undefined, unbounded, no medicine is actually going to be 
shown to be strong enough, not even if Eric gets tired fighting that 
corner and names some specific algorithm and key size as 'enough' (for 
what?).

So I don't think we can talk sense and arrive at a technically reasoned 
consensus about disabling attacks until we make a set of attacks that we 
accept need to be disabled by the solution, and all other attacks are 
not our problem.

> data with out using a reserved bit

I see what you're trying to do there with squeezing out the detail that 
will be debated while establishing munging, but I ask you is it a good 
idea to add this into a specification when you cannot actually describe 
in all honesty exactly what it is trying to achieve and why it is 
sufficient to achieve it?

-Andy

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 11:03:13 +0100

> We don't know, and can't tell without experiment.

In fact, starting with CRLF should not change anything because HTTP
recommends that implementations skip over CRLFs in request in order
to accomodate for broken clients that used to send CRLFs after POST
requests.

Also, I think the smallest request we could fear would be the HTTP/0.9
"GET /\n". It's 6 bytes long. Whatever crypto algorithm is used, it
will always be enough to send 6*256^6 bytes (about 1600 TB) to make
it appear in the stream, and some clever constructs might be able to
make it appear in only 256^6. That also means that any key larger than
6 bytes (48 bits) is pointless to protect against this request, whether
we use a simple XOR or a cryptographically strong algorithm.

In practice, it could happen a lot earlier because the key might just
itself contain the pattern we're trying to avoid.

> likes,

I disagree with these last few words, because I said that I liked the
principle because eventhough it's dirty, it's a way to force some broken
intermediaries to act in a more or less deterministic way.

> would be sufficient to reduce attacks to a percentage of  

Please note that none intermediaries vulnerable to what we're trying
to fix have been found to date either.

> given that experimental data at least supports the unicorn's  

You got me lost there.

> measurable levels - despite all reasonable expectation to the  

The rise of vulnerable intermediaries will probably happen, because
Adam and Eric's experiment showed that intermediaries vulnerable to
HTTP do exist. The same that have been abused by their experiment
might still be in the wild since nobody knows which ones were abused,
and we know it only requires a shared hosting service to exploit them.
The client may be anyone with an internet connection as it only requires
the ability to forge an HTTP request. (In fact, I even hope that those
crappy intermediaries will quickly be uncovered, that will make the net
a cleaner place).

But we've not got any evidence of an intermediary that is able to
spot something looking like a valid request after the framing and we're
several ones to have strong doubts about that.

I'm not saying we should avoid masking, having it mandatory for the
browsers will help us sleep in peace. But I sometimes would like to
remind what we're trying to protect against vs what it costs to do it.
When I'm saying that an attacker needs to send 52 GB of WS messages
with 32bit keys to have "GET /\n" sent over the wire, hoping for an
intermediary to pick it, while it would only have required a telnet
to port 80 to reliably send it, I think we have a strong enough balance
so that WS is not a usable attack vector anymore.

> forcing us to mask every byte on the network for no reason whatsoever.

I don't think that masking is that much relevant, it's just that it
saves us from verifying hypothesis. That's a choice that was proposed
to move forward, as all hypothesis of supposed vulnerabilities have
remained unverified and unverifiable.

> Let's base our solution on that, and not go dashing off into  

I think that payload masking can have other advantages for totally
unrelated reasons. For instance, if we design it as an extension,
it might be usable to safely transmit asymetrically encrypted
keys or passwords over the network with a key presented in the
hello frames. But that's assuming we accept to make masking optional
and negociable.

Willy

---

From: Greg Wilkins <[email-masked]>
Date: Fri, 7 Jan 2011 11:09:07 +0100

On 7 January 2011 10:42, Andy Green <[email-masked]> wrote:
> websockets without munging, so we can go on, that's a price worth paying IMO
> (even though I think all of it is pointless and a problem to be solved at
> the intermediary only).

Andy,

as much as I personally agree that sending some stream and/or frame
prefix should be sufficient to defend against poor intermediaries,
that line of argument has been made many many times and has uniformly
failed to convince the browser vendors that speak in this WG.

So unless they have a sudden change of heart/mind (???), then I really
think the only way forward is along the lines of the consensus  that
started forming around masking.    But for that to work, those that
don't think masking is needed must stop trying to convince others that
it is not needed, and those that think masking is cheap and simple
must stop trying to convince others that there is no cost in making it
mandatory in all deployments.

regards

---

From: Andy Green <[email-masked]>
Date: Fri, 07 Jan 2011 10:29:30 +0000

> started forming around masking.    But for that to work, those that

I agree, as a political situation regardless of the technical reality 
the browsers need a reason to re-enable websockets after disabling it 
for 'security'.

> mandatory in all deployments.

Since my use case for websockets involves a browser, like pretty much 
everybody else, when the browser makes munging mandatory by default it 
will be mandatory for me in fact.

There's no possibility to reach a reasoned, technical decision about 
defeating attacks without defining the attacks that need to be defeated.

If that isn't going to happen, then just making the spooked browser guys 
happy again by throwing crypto voodoo into the mix is as good as 
anything else, at the cost of stinking up this nice lightweight protocol 
for no perceptible benefit.

-Andy

---

From: Greg Wilkins <[email-masked]>
Date: Fri, 7 Jan 2011 11:31:41 +0100

On 7 January 2011 10:59, Andy Green <[email-masked]> wrote:
> I ask you is it a good idea to
> add this into a specification when you cannot actually describe in all
> honesty exactly what it is trying to achieve and why it is sufficient to
> achieve it?

Andy,

I can in all honesty describe the vulnerability that masking is trying
to defend against.

WS, by it's nature is designed to penetrate HTTP infrastructure, some
of which is unaware of the ability of HTTP to be upgraded to a
non-HTTP protocol.

There is a demonstrated vulnerability in some intermediaries that they
can have their caches poisoned by seeing spoofed host headers in a
request sent to an attacker controlled server.   However, this
demonstration only  HTTP compliant framing.

There are other demonstrations of HTTP parsers that are very forgiving
of at least some type of rubbish data between requests such that
unknown methods and white space are skipped while the next request is
looked for.

There is a concern that there might exist intermediaries that suffer
from both cache poisoning vulnerability and overly forgiving HTTP
parsing.  If so, WS could be used to attack these intermediaries and
poison their caches.   While such intermediaries are already
vulnerable to flash and java plugins, these are optional extras in
browsers, so it is a different matter to expose the same vulnerability
in the protocol behind a non-optional part of the HTML-5 standard.

Now, I personally believe that the existence of intermediaries with
both vulnerabilities is vanishingly small and probably zero.  I also
believe that sending Hello frames and using framing with high bits set
should be sufficient to break even the most forgiving of HTTP parsers.
   But I can not prove either point, nor after months of debate have
the browser vendors been convinced of the validity of such arguments.

Thus in the spirit of compromise, as an implementer or servers and
non-browser clients, I'm prepared to accept a masking extension that
removes the ability of attackers to send any predictable clear text in
any frame and that this extension is mandatory for browsers.  All I
ask in return is when a connection is established by consenting
parties that do not share the concern about such intermediaries, that
there be a realistic option to turn off the masking (or replace it
with something else).  OK - I'm also asking that we don't go overboard
with an elaborate masking algorithm - surely XORing a random key is
sufficient?

Technically, I believe that it is very important that WS has a viable
extension mechanism. While I'm not entirely convinced of the need for
masking on the grounds of security, I think it's value as an exemplar
that will ensuring we have a viable extension mechanism is
significant.

regards

---

From: Andy Green <[email-masked]>
Date: Fri, 07 Jan 2011 10:42:24 +0000

> to accomodate for broken clients that used to send CRLFs after POST

Thanks for the insight... "+\x0d\x0a\x0d\x0a" then?

-Andy

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 11:46:17 +0100

> demonstration only  HTTP compliant framing.

Indeed and it can also be done without involving a browser at all, just
by sending a hand-crafted request to the faulty component.

> unknown methods and white space are skipped while the next request is

Such components generally are the ones that don't use the method, for
instance, content switches that are just looking for host headers and
maybe URI. Since a cache must check the method (at least to differentiate
between HEAD/GET/POST), it could not blindly ignore it.

> vulnerable to flash and java plugins,

And to any incoming connection whatever the component which initiates
it, I find it important to remind it.

> these are optional extras in
> both vulnerabilities is vanishingly small and probably zero.

Agreed.

> I also

Agreed too.

> with an elaborate masking algorithm - surely XORing a random key is

I too would be happy with that. In my opinion it would be technically
useless, but technically cheap enough to justify having it, and it will
make browser vendors feel better after what we tried to make them swallow.

> that will ensuring we have a viable extension mechanism is

That's a good point. Just like TCP was released with the MSS option as
the single one at the beginning.

Regards,
Willy

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 11:53:27 +0100

> Thanks for the insight... "+\x0d\x0a\x0d\x0a" then?

We should avoid restarting this debate, it has already been suggested
to send strings supposed to make intermediaries abort on invalid requests,
but since the fears about the broken one sometimes rely on their supposed
ability to spot anything anywhere, such methods cannot be convincing for
these people.

If we want to send something that looks like a request, Dave is right, the
experiment has only shown that CONNECT was respected. And if we wanted to
go that route, we could only use what was proven by the experiment to reassure
the people that were worried by the interpretation of the same experiment.

Quite frankly, I'd prefer to be able to send a clear stream when possible,
which means that optional masking is a good solution. 10 years from now,
people will not say "why do we have to send a fake request after the
handshake ?", at best they'll say "pfff this stupid masking has been
unused for 5 years still we have to implement it", and that will mean
we'll have already succeeded.

Willy

---

From: Andy Green <[email-masked]>
Date: Fri, 07 Jan 2011 11:11:34 +0000

> ability to spot anything anywhere, such methods cannot be convincing for

Yeah but this is the bind, if we accept it is websocket responsibility 
to defeat attacks on an intermediary that has the "supposed ability to 
spot anything anywhere" as you say, then they will eventually spot 
something even in a munged stream.  This troll intermediary is actually 
broken for use on a network at all, presumably it has a special get-out 
that it never spots crap on ssl.

That's why I say no obfuscation key length is enough to satisfy the 
demand to protect the "anything anywhere" case, the demand is 
unreasonable and we should reject it and require these broken 
intermediaries get fixed themselves.

> we'll have already succeeded.

Like I said for me if it only takes CONNECT in the handshake or a few 
extra bytes in the framing and the rest is in clear, that is hugely 
preferable to munging every byte.

-Andy

---

From: Dave Cridland <[email-masked]>
Date: Fri, 07 Jan 2011 11:15:28 +0000

> to fix have been found to date either.
Not quite - the vulnerabilities have been found given a plain  
Upgrade-based handshake followed by syntactically correct HTTP  
requests and responses. There is some argument, much of it reasonable  
(if not absolutely convincing) that it follows that with a pure  
Upgrade-based handshake, intermediaries may "find" HTTP traffic  
within some framing.

> > given that experimental data at least supports the unicorn's

Let's step into a parallel universe, for a moment. After all,  
everyone else is.

In this hypothetical world, Adam conducts his advertising experiment  
and discovers that actually, no intermediaries he can find are  
vulnerable. But if they were, he notes that cryptographic masking  
would be sufficient to disable the attack.

Would the working group consider masking in this parallel universe?  
Of course not, because that would be silly.

In our real universe, however, Adam conducted his experiemnt and  
found that by sending a CONNECT, he could no longer find any  
vulnerable intermediaries. He notes that if there were, cryptographic  
masking would be sufficient to disable the attack. One might think  
that the same logic applies, and that the working group would  
universally nod, use the provided solution, and move on, without  
considering the masking which Adam has clearly demonstrated is  
superfluous by experiment.

But no, the working group decides that yes, yes we will indeed do  
masking in spite of the evidence.

Now, if I assert that no such intermediaries exist, I'm supported by  
experimental data - an experiment which, in case it needs to be said,  
I had nothing to do with. I can't absolutely prove my assertion,  
because proof of non-existence would require an exhaustive survey.  
However, disproving my assertion would require a less than exhaustive  
survey - and a reasonably high survey has been carried out without  
success.

If I add, to my assertion, that I know so because an imaginary entity  
told me so, it remains equally valid, and to disprove the imaginary  
entity is again a proof of non-existence.

> The rise of vulnerable intermediaries will probably happen,

No - I think you simply misunderstood what I meant, rather than  
disagreeing with me. (I hope so, anyway).

It seems probable than one or two will be found, certainly, but it  
seems highly unlikely - given experimental data - that these  
represent a significant threat.

If we assume that the experimental sample was skewed by 50% - ie, the  
numbers of vulnerable intermediaries are 50% higher than it would  
suggest - then we have roughly 1 in every 25,000 intermediaries  
vulnerable.

Now, assuming that every single person on the whole internet has a  
proxy of some form, that would mean that 80,000 vulnerable proxies  
exist amongst the 2 billion internet users. I don't think this is a  
sufficient attack surface to worry about, especially given that these  
represent intermediaries that are already vulnerable to attacks of  
the form we're trying to protect against by using Flash or Java.  
(And, maybe, ActiveX?) One assumes that, therefore, these will be  
fixed, and not just due to websockets, but due to the far more widely  
used rich content technologies of today. That is, to be clear - even  
if we deploy masking, these intermediaries will be fixed.

So, my assertion is that this number will be the upper bound - ie,  
this number will drop (probably quite rapidly) - and will not rise.

Dave.

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 12:34:36 +0100

On Fri, Jan 07, 2011 at 11:11:34AM +0000, Andy Green wrote:
> something even in a munged stream.

Yes it will. But this will require much more data to be sent to make
the "anything" appear than if we can put the "anything" on the wire
as-is.

>  This troll intermediary is actually 
> broken for use on a network at all,

That's what I've been saying for some time too. And I really guess that
this intermediary is on no network at all anyway :-)

> presumably it has a special get-out that it never spots crap on ssl.

No, most likely it requires a specific header that we'll have to
define :-)

> preferable to munging every byte.

It depends how it can be removed later and how we can prove it's enough.
The problem with a CONNECT request is that we have to ensure that either
it always fails or that it always works (harder). There will always remain
some doubts about "what if an intermediary silently ignores them and scans
the remaining stream to search for a cacheable GET request"...

In my opinion, neither the CONNECT nor masking are necessary. Technically
the CONNECT offers much more control and relies less on luck than the
masking. But as it requires better understanding of protocols, it does
not have the psychological effect of "look, now the requests are masked
so your browsers are safe again, isn't it beautiful ?". And clearly what
we're looking for now is something that will be easy to understand for
people who don't understand the basics of the underlying protocols. And
I'm convinced that payload masking has this magical effect we're looking
for with a low cost.

Regards,
Willy

---

From: Dave Cridland <[email-masked]>
Date: Fri, 07 Jan 2011 11:36:11 +0000

On Fri Jan  7 10:29:30 2011, Andy Green wrote:
> I agree, as a political situation regardless of the technical  
> reality the browsers need a reason to re-enable websockets after  
> disabling it for 'security'.

Remember that whatever solution we propose for Websockets will also  
need to be proposed for Flash and Java, which are both considerably  
easier to exploit as an attck generator now, and also much more  
widely used - after all, it was using one of these technologies that  
the vulnerabilities were demonstrated.

Re-enabling these two technologies would seem, if anything, to be a  
greater priority, given the current reliance on them.

I'm assuming, of course, that the browser vendors actually disabled  
those, too, due to security, right? I'd hate to think they'd only  
disable the attack vector least likely to be useful, all in the name  
of "security", because that would be just laughable, right?

Dave.

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 12:56:04 +0100

On Fri, Jan 07, 2011 at 11:15:28AM +0000, Dave Cridland wrote:
> requests and responses.

Yes precisely. But the framing is all but syntactically correct
HTTP requests and responses.

> There is some argument, much of it reasonable  

I think that all the people who are thinking that should at some
point try to write some working code to implement a real caching
intermediary. They will see that they need to check the method
and that you cannot randomly skip over garbage to presume your
method will be here or there. Such a code would already have
trouble with requests such as "POST /path/GET HTTP/1.1" or even
with data looking like methods in headers or payload. Yes a
simple content switch can be lazy, failures will have limited
impact. But a cache cannot be that lazy.

> superfluous by experiment.

Well, to be honnest, he did not exactly test what you are suggesting.
He compared the GET+Upgrade followed by valid HTTP requests with CONNECT
followed by valid HTTP requests and concluded that GET+Upgrade was
sometimes failing where CONNECT did not. That does not mean that
GET+Upgrade followed by a CONNECT is always OK. While our intuition
lets us guess so, it has not even been tested. And as I explained in
another mail, accepting that this complex design be more robust than
the initial one that was accused of failing will not be easy for those
who don't understand the basics of the underlying protocol.

> survey - and a reasonably high survey has been carried out without  

You like to stack up negations in your assertions... It's hard to 
follow you. So you're saying that a survery did not succeed in disproving
your assertion that no broken intermediaries exist ?

> entity is again a proof of non-existence.

I'm lost again, sorry.

> suggest - then we have roughly 1 in every 25,000 intermediaries  

Vulnerable to valid HTTP requests, let me insist on that once again,
we've never found one vulnerable to WebSocket.

> the form we're trying to protect against by using Flash or Java.  

And telnet, netcat, etc... No need to look for plugins when everyone
has an internet connection which is enough to abuse them.

> if we deploy masking, these intermediaries will be fixed.

Exactly, that's why I'm advocating for strong protocol compliance.
We can't force intermediaries to implement new protocols, but we
can have them quickly fix their security issues.

> this number will drop (probably quite rapidly) - and will not rise.

I think the number of really vulnerable intermediaries (vulnerable to
HTTP requests) will indeed drop, but their knowledge will rise with the
interest around them that Adam's paper should suggest. Because basically
right now those intermediaries can be fooled by anyone behind them as
easily as :

  $ printf \
    "GET / HTTP/1.1\r\nHost: my.fake.site.com\r\nUpgrade: WebSocket\r\n\r\n" \
    "GET / HTTP/1.1\r\nHost: victim.com\r\n\r\n" > /dev/tcp/my.fake.site.com/80

So surely it will raise some interest ;-)

Cheers,
Willy

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 12:59:41 +0100

> of "security", because that would be just laughable, right?

Why do you think that the situation suddenly must not be laughable anymore ?
We're trying to make 0.001% of the users avoid to deliberately attack known
vulnerable components which are exposed to larger parts of the net.

Granted we can make some efforts to avoid the simple cases but those efforts
should be reasonably limited once the cost becomes non-null.

Willy

---

From: Maciej Stachowiak <[email-masked]>
Date: Fri, 07 Jan 2011 06:34:39 -0800

> That means a 20% CPU overhead imposed by masking then.

I would hope a server handling 1 million concurrent connections is considerably more powerful than a single core of a MacBook Air.

Regards,
Maciej

---

From: Dave Cridland <[email-masked]>
Date: Fri, 07 Jan 2011 14:41:48 +0000

On Fri Jan  7 14:34:39 2011, Maciej Stachowiak wrote:
> >>> Well, at 1 million concurrent connections with a 5s think time,  
> that's
> >>> about
> I would hope a server handling 1 million concurrent connections is  
> considerably more powerful than a single core of a MacBook Air.

It'd have to be because of the masking.

The thing is, I can quite easily see cases where BOSH or some other  
long-poll is going to be more efficient for servers to handle just  
because of the masking overhead.

Dave.

---

From: Andy Green <[email-masked]>
Date: Fri, 07 Jan 2011 15:15:49 +0000

> in the protocol behind a non-optional part of the HTML-5 standard.

Thanks, that is quite concise describing what "masking" aka munging is 
meant to solve, assuming it's generally held agreed.  At least nobody 
has poured scorn on it yet so let's assume that is the attack websockets 
is supposed to stop.

How about this alternative solution for people who think the above is 
realistic: extend the handshake to deliberately send a websocket frame 
which (accepting the intermediary has dumb HTTP parsing and ignores the 
framing) trying to poison the cache at a random and unlikely URL path, 
then connect to the server in http again and confirm the poisoned path 
is a 404 before allowing the connection.

So, it's

  1) normal -03 handshake
  2) send an initial  frame to be discarded by the server, containing a 
good-looking HTTP poisoning action for a URL like 
"/__websocketcheck/<random integer>" inside websocket framing
  3) try to GET "/__websocketcheck/<random integer>", die if it exists
  4) otherwise, enjoy a non-munged websocket life

Of course, after a while when the number of hits on the test URL remains 
at 0, or the troll proxies are identified and updated, this can be 
removed from the handshake.

-Andy

---

From: John Tamplin <[email-masked]>
Date: Fri, 7 Jan 2011 11:02:53 -0500

On Fri, Jan 7, 2011 at 10:15 AM, Andy Green <[email-masked]> wrote:
> realistic: extend the handshake to deliberately send a websocket frame which
> (accepting the intermediary has dumb HTTP parsing and ignores the framing)
> trying to poison the cache at a random and unlikely URL path, then connect
> to the server in http again and confirm the poisoned path is a 404 before
> allowing the connection.
>
> So, it's
>
>  1) normal -03 handshake
> good-looking HTTP poisoning action for a URL like "/__websocketcheck/<random
> integer>" inside websocket framing
> Of course, after a while when the number of hits on the test URL remains at
> 0, or the troll proxies are identified and updated, this can be removed from
> the handshake.

Personally, I find requiring extra round trips during the handshake
far more objectionable than a small amount of per-byte processing
overhead.

---

From: Greg Wilkins <[email-masked]>
Date: Fri, 7 Jan 2011 17:08:18 +0100

Andy,

the problem is that sending a single poisoning attack that fails does
not prove that all poisoning attacks will fail. Maybe the intermediary
needs special cache-control headers for it to work, or maybe the
particular injection was not found, but it is still scanning and might
see a subsequent phantom request.

The fundamental problem with this line of solution, is that you
inevitably have to ask the question: "is this good enough?"  But  we
have no definition or agreement what "enough" is!

It was hoped that masking would remove the possibility of clear text
and thus avoid the attempt to detect or trip up bad intermediaries.
Unfortunately we are now in the: "is this masking good enough?" game
:(

cheers

On 7 January 2011 16:15, Andy Green <[email-masked]> wrote:
> Thanks, that is quite concise describing what "masking" aka munging is meant
> to solve, assuming it's generally held agreed.  At least nobody has poured
> scorn on it yet so let's assume that is the attack websockets is supposed to
> stop.
>

---

From: John Tamplin <[email-masked]>
Date: Fri, 7 Jan 2011 11:09:35 -0500

> So surely it will raise some interest ;-)

And if simply clicking on a link in a browser could cause that code to
be executed on their machine, then yes this would be equally
exploitable.

---

From: Andy Green <[email-masked]>
Date: Fri, 07 Jan 2011 16:18:04 +0000

On 01/07/11 16:02, Somebody in the thread at some point said:
> On Fri, Jan 7, 2011 at 10:15 AM, Andy Green<[email-masked]>  wrote:

> far more objectionable than a small amount of per-byte processing

There is a whole extra socket establishment and HTTP transfer both ways 
with this method, not a simple roundtrip, so it is pretty expensive for 
each websocket setup while it is used.

However, it will allow you to exactly perform the internet-wide probing 
for these alleged broken intermediaries, pretty much starting 
immediately.  Just mandate the probe in the protocol.

Whe.. I mean if it is shown these problem intermediaries don't exist, if 
you use a header line to warn the server you will be sending a probe 
packet that should be ignored, this extra connection and roundtrip can 
be turned off at any time compatibly.

-Andy

---

From: Dave Cridland <[email-masked]>
Date: Fri, 07 Jan 2011 16:39:45 +0000

> be executed on their machine, then yes this would be equally

But you *can* arrange for equivalent code to be executed on the  
machine by a click on a link - indeed, that's exactly what the  
experiment did. Just with Flash.

The fact is that even if we did nothing at all in WebSocket to  
mitigate against this attack, a wannabe attacker will *still* use  
Flash over WebSocket as a mechanism because it'll present a far  
higher success rate. Mostly because Flash has a vastly greater  
deployment, but also because while the effects of framing might be  
unknown, it can only decrease the effectiveness of the attack.

Dave.

---

From: John Tamplin <[email-masked]>
Date: Fri, 7 Jan 2011 11:42:55 -0500

On Fri, Jan 7, 2011 at 11:39 AM, Dave Cridland <[email-masked]> wrote:
> But you *can* arrange for equivalent code to be executed on the machine by a
> click on a link - indeed, that's exactly what the experiment did. Just with
> Flash.
>
> The fact is that even if we did nothing at all in WebSocket to mitigate
> against this attack, a wannabe attacker will *still* use Flash over
> WebSocket as a mechanism because it'll present a far higher success rate.
> Mostly because Flash has a vastly greater deployment, but also because while
> the effects of framing might be unknown, it can only decrease the
> effectiveness of the attack.

I don't know the current status of the vulnerability in Flash/Java,
but since publishing the experiment results was delayed by a couple of
months to give them time to react to it, hopefully it has been or will
soon be fixed.

---

From: Andy Green <[email-masked]>
Date: Fri, 07 Jan 2011 16:20:09 +0000

> not prove that all poisoning attacks will fail. Maybe the intermediary

Some dudes are claiming that they have been going around actually 
poisoning caches via websocket, let's get started with their magic 
packet contents and reproduce their test widely using the protocol itself.

-Andy

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Fri, 7 Jan 2011 08:56:14 -0800

On Fri, Jan 7, 2011 at 8:20 AM, Andy Green <[email-masked]> wrote:

> Some dudes are claiming that they have been going around actually poisoning
> caches via websocket, let's get started with their magic packet contents and
> reproduce their test widely using the protocol itself.
>
>
Andy, you are missing the point. The point is not to stop a single known
attack, the point is to come up with a solution that we can reason about and
feel comfortable that we understand why such attacks in general, not a
specific instance, are prevented. The general threat brought up is attackers
being able to send plain-text content that can confuse intermediaries,
masking is a solution that has been proposed to remove that capability from
attackers. With masking, we can actually reason about why an attacker cannot
do things, as opposed to just guessing at what black-box intermediaries may
or may not do.

-Ian

---

From: Scott Ferguson <[email-masked]>
Date: Fri, 07 Jan 2011 09:45:03 -0800

Willy Tarreau wrote:
> method will be here or there.

+1

Those arguments have been handwaving based on an ignorance of what a 
HTTP intermediary does. (And apparently ignorant of how framing works in 
general.)

If framing breaks, an intermediary (or server) cannot just skip bytes in 
some kind of error recovery system until it find something it likes. It 
has to terminate the connection. That's not a security requirement; it's 
basic protocol requirement to avoid parsing junk.
 
> He compared the GET+Upgrade followed by valid HTTP requests....

In other words, the test used valid HTTP framing followed by another 
HTTP request. There was no test where HTTP framing was deliberately 
broken as it is in WebSockets.
> has an internet connection which is enough to abuse them.

+1

-- Scott

---

From: Maciej Stachowiak <[email-masked]>
Date: Fri, 07 Jan 2011 10:10:28 -0800

On Jan 7, 2011, at 6:41 AM, Dave Cridland wrote:

> The thing is, I can quite easily see cases where BOSH or some other long-poll is going to be more efficient for servers to handle just because of the masking overhead.

A more plausible server configuration could probably do at least an order of magnitude better on SHA-1 ops/sec, which would lower the overhead to 2%, given these assumptions. Would you consider that unacceptable overhead?

Regards,
Maciej

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 19:58:01 +0100

> I would hope a server handling 1 million concurrent connections is considerably more powerful than a single core of a MacBook Air.

Handling connections is not a matter of having a big CPU bit just large
amounts of RAM. What's important is to consider the cost of doing things
that are sometimes not needed at all. Doing an HMAC-SHA1 will involve 2
SHA1 operations (40% CPU above, I forgot the factor of two). As Eric said,
the operation by itself can be relatively cheap, but still it's a lot more
expensive than the work that was supposed to be done. In short, instead of
doing this in a front proxy :

   read(in, buf, 10);
   length = parse_length(buf);
   write(out, buf, 10);
   splice(in, out, length - 10);

with parse_length() basically adding a few bytes with a few if that way :

   length = buf[1] & 0x7F;
   if (length == 0x7E)
      length = (buf[2] << 8) + buf[3];
   else if (length == 0x7F)
      length = (buf[2] << 56) + (buf[3] << 48) + ... buf[9];
   return length;

You'll have to run something like this :
 
   read(in, rnd, 6);  // assuming we'd use 6 bytes for the key
   key = compute_hmac_sha1(c_nonce, s_nonce, frame_num, rnd);
   read(in, buf, 10);
   decode(buf, tmp, key, 10);
   length = parse_length(tmp);
   write(out, rnd, 6);
   write(out, buf, 10);
   splice(in, out, length - 10);

The hmac computation above while not a big deal still represents a
substantial cost compared to the simple decoding and short read/writes.

Once again, I'm not saying it's a big blocking issue, I'm saying that
it's way overkill to protect the 6 bytes that reprenset the smallest
supposedly vulnerable request we can think of (having a key larger than
the data to hide brings nothing, and we don't want to prevent anybody
from deciphering the stream, we just want it to be non-deterministic
from the server's POV).

Regards,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 7 Jan 2011 11:01:02 -0800

We're going around in circles.

It's your position that masking with a keystream as long as the message is
overkill. It's my position
that the alternative you're pushing isn't demonstrably secure. Obviously,
I'm not convincing you
and your arguments certainly haven't convinced me. I'm now going to stop
responding on this
point until something new is said. Please do not take that as agreement with
your position. It is
not.

-Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 21:39:58 +0100

On Fri, Jan 07, 2011 at 11:01:02AM -0800, Eric Rescorla wrote:
> overkill. It's my position that the alternative you're pushing isn't
> demonstrably secure. Obviously, I'm not convincing you and your arguments
> certainly haven't convinced me. I'm now going to stop responding on this
> your position. It is not.

Eric, you're probably the one who knows all the theory around crypto better
than anyone else here, still you don't explain what elements you're using
for your choices, so it's very hard to understand some key points behind
that, and it's normal to challenge them especially when the proposals come
with a cost. If you have a reason to think that a long and complexly built
key is more efficient at preventing someone to make a 48-bit long text appear
in a stream than it is using a 48-bit key, then please explain to us why.

At my level of knowledge, we're sure to make that choosen text appear
if we send all possible 48-bit patterns, whatever the key length, key
value and crypto method used. That means that sending 6*2^48 = 1.6 PB
of payload *will* definitely make the choosen text appear.

For this reason I fail to understand the point of using larger keys.
I believe you said that 32-bit was not long enough for you, but I fail
to understand how you can reliably make the message appear without
exhausting the key space. Even if we assumed that clever constructs
might create sequences which can match under multiple forms, you'd still
have to send at least 4 GB of data to cover the entire key space (I
even suspect it's 4G+1 though I cannot demonstrate it). I even proposed
variable key lengths so that the size required to exhaust the key space
would always be larger than the largest possible message. This is
something which makes sense to me, but maybe I'm wrong.

You often ask for provably secure systems. I try to show with my little
knowledge that the risks are in line with the context, but you just keep
saying I'm wrong without even a piece of explanation. Right now we're
just with "I would be more comfortable with this or that". I know that
intuition from experience is something to be taken into account, but we
are talking about finite systems, so we should be able to talk about
quantities.

Finally I end up doing the maths myself while I'm not the one skilled to
that task. That's not a fair way of participating and making progress. So
please explain me why you think I'm wrong if you do, and if it convinces
me, it will at least stop me from defending a mechanism you don't agree
with and it might educate me as well as possibly other persons here.

Thank you,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 7 Jan 2011 13:19:13 -0800

> in a stream than it is using a 48-bit key, then please explain to us why.

I don't know what a "long and complexly built key" means, but I think I've
explained
myself several times.

My objective is to make the bits that appear on the wire indistinguishable
from random
from the attacker's perspective. I think it's clear that this is the
strongest form of masking
available, and the method I proposed does that. A sliding mask does not
produce this
result because it means that an attacker can have any relationship he wants
between
bits which appear at the same offset in the mask. As I've now said a number
of times,
I am unaware of an attack which exploits this property, but that does not
mean there
isn't one, and so I prefer to have a stronger mechanism.

It's important to recognize that this is a distinct question from the
*entropy* of the
mask. For instance. if you start with a 32-bit random seed and use that to
generate
an arbitrarily long mask, this provides more resistance to the above
property than
just using the key directly as a repeating mask. Which is precisely the
point of using
an expansion function for the mask (whether HMAC-SHA1, or AES-CTR).

> that task. That's not a fair way of participating and making progress.

I'm sorry, but this is simply nonsense. I've explained my position. If
you're not convinced,
that's fine, but there's nothing "unfair" about my refusal to engage in an
endless discussion
about it.

-Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 7 Jan 2011 23:23:12 +0100

> an expansion function for the mask (whether HMAC-SHA1, or AES-CTR).

Thank you for this explanation. Now I understand better what you're trying
to achieve. Yes I agree that the repeating mask is a lot weaker than a
sliding mask, because in order to send a predefined message, the server
would just have to establish the relation between the multiple bytes and
send it as many times as the key space permits. But still that *a lot*.
Sending the 6-bytes "GET /\n" 2^32 times each time encoded with one
different key is still 24 GB long.

My position is clear on this point, we're not trying to build something
*that* secure, we're trying to avoid a lazy intermediary from finding a
method using strstr("GET ") in a stream it has in its request buffer.
If an attacker is able to make a browser send 24 GB of data to an
arbitrary location without anyone noticing, surely there are much more
fun to do than just trying to corrupt one entry in a cache.

Now maybe we can also build a sliding mask with something very simple
without involving expensive computations at all, but given the goals
of the suggested masking, I really think that it will bring nothing
at all in this precise context.

Obviously, would someone propose to encrypt my password using such
a masking method, I would categorically refuse and would approve
your proposal without hesitation. But we're not trying to do that
right now.

Regards,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 7 Jan 2011 14:27:08 -0800

Yes. I understand your position. However, as I stated, I disagree.

I'd possibly be willing to live with a relatively long mask (e.g., 160 bits)
generated from
a shortish (4-8 byte) key. I oppose anything shorter.

-Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 8 Jan 2011 01:15:49 +0100

> Yes. I understand your position. However, as I stated, I disagree.

I'm seeing that you disagree though I really don't get why considering
the balance of risks vs costs in some situations :-/

> generated from a shortish (4-8 byte) key. I oppose anything shorter.

OK. My concerns are to avoid per-message setup costs as well as reducing
internal states. Would it be OK for you if we used either a rotating 256
bit mask derived from the rotation of a 32 bit one, or even an infinite
length one constructed by iterating over a combination of the rotating
mask and the output data ? Such constructs are simple, fast and don't
permit the attacker to establish relations between message parts when
he doesn't know the key.

For instance, below is what we find when sending 100 times "GET /\n" with
the first method (it does obviously repeat itself) :

 76 26 92 ac 37 3b 24 83 d8 39 1d 6f 8d d1 7d 72
 8a 41 d1 68 0e 95 45 df ec 13 f8 79 9c 6c 8b dd
 65 43 e9 86 5f 74 37 e6 a3 13 75 20 9e b4 06 58
 e2 0e c2 0d 75 bf 2d 90 ff 76 83 53 f4 23 98 b8
 1e 69 81 c9 4c 11 4c cc cb 5c 66 45 e5 9e 6e 17
 f1 6b b9 27 1d f0 3e f5 84 5c eb 1c e7 46 e3 92

 76 26 92 ac 37 3b 24 83 d8 39 1d 6f 8d d1 7d 72
 8a 41 d1 68 0e 95 45 df ec 13 f8 79 9c 6c 8b dd
 65 43 e9 86 5f 74 37 e6 a3 13 75 20 9e b4 06 58
 e2 0e c2 0d 75 bf 2d 90 ff 76 83 53 f4 23 98 b8
 ...

And the second one does not even repeat at all :
 85 4c 0a e6 5c 48 8a 61 fd 6f 21 34 f7 1d 99 14
 53 41 90 7b ac bc da ce 10 fb 23 32 79 2c 3e 75
 82 0e 44 10 02 c9 b6 5a 61 f4 b6 dd 5a 57 6a ff
 ae c4 92 3f 52 47 a6 2c ab 89 f4 a1 b0 da 4c 5c
 7a 2f 3d 77 8f 65 df ca 0c e6 78 f0 bf ea ec 07
 d8 d1 9c 09 48 22 a4 a4 82 d7 d6 bc fb 79 03 56
 49 23 bb ba c0 94 96 7d ba b6 cc 98 fb 36 49 a4
 83 d1 cf 9a 0d 9f 31 67 05 cc 8b 6a d1 c4 27 a2
 25 28 17 82 d5 bc fb 7a 01 57 55 3c 7a f7 8a de
 c0 8a 7c ec aa bf 6e 84 52 7f 12 87 e6 6d ea 46
 3c 68 6a 81 5e 53 15 83 d1 b8 e6 6b 2d 3b da 50
 2e 02 68 fd ac c7 98 10 5e 4a 8c 66 f8 70 3e 6b
 6a 81 5e 52 18 8c de 55 21 2c 6b fe a0 2a 5c 4c
 0b 5e 40 0b fc 6c 2a 3e e0 6a 9c 0c 4a 1f 0e e5
 71 9c 3b 6e 70 9b 0c 9c 3a 6e 70 9b 0c 9c 3a 6e
 70 9b 0c 9c 3b 6e 71 9b 03 92 d9 cf 1d 97 6f c6
 bd eb e9 03 db da e1 77 35 5f c7 ce 85 d3 c1 8b
 73 e2 49 1c 0f e5 71 9c 3a 6e 70 9b 0c 9c 3a 6e
 70 9a 0d 9f 31 67 05 cc 8a 67 da cf 1e 94 62 ef
 a2 b6 68 82 44 45 20 34 f6 1c 9a 17 aa be 60 ea
 1c 8c ca 9f 8e 64 f2 1f b1 e7 86 4c 0a e6 5c 48
 8a 61 fe 72 38 6c 7f b5 c1 cc 8b de c1 88 77 9d
 ...

With a constant input stream, the difference is more obvious,
let's feed it 256 'A', we see the repeating pattern every
256 bit for the first method, and none for the second one.
In fact, with a 8-bit rotating key, the second makes the
pattern loop every 256 bytes on this text, and every 64k
for a 16-bit key, but here in the examples I used a 32-bit
key :

method 1 :
 fa 36 af 9d f8 32 a6 8f dc 7b 35 a9 91 e0 02 c6
 4f 5d 78 33 a5 89 d0 62 07 cc 5b 74 2a 96 ef 1c
 fa 36 af 9d f8 32 a6 8f dc 7b 35 a9 91 e0 02 c6
 4f 5d 78 33 a5 89 d0 62 07 cc 5b 74 2a 96 ef 1c
 fa 36 af 9d f8 32 a6 8f dc 7b 35 a9 91 e0 02 c6
 4f 5d 78 33 a5 89 d0 62 07 cc 5b 74 2a 96 ef 1c
 fa 36 af 9d f8 32 a6 8f dc 7b 35 a9 91 e0 02 c6
 4f 5d 78 33 a5 89 d0 62 07 cc 5b 74 2a 96 ef 1c
 fa 36 af 9d f8 32 a6 8f dc 7b 35 a9 91 e0 02 c6
 4f 5d 78 33 a5 89 d0 62 07 cc 5b 74 2a 96 ef 1c
 fa 36 af 9d f8 32 a6 8f dc 7b 35 a9 91 e0 02 c6
 4f 5d 78 33 a5 89 d0 62 07 cc 5b 74 2a 96 ef 1c
 fa 36 af 9d f8 32 a6 8f dc 7b 35 a9 91 e0 02 c6
 4f 5d 78 33 a5 89 d0 62 07 cc 5b 74 2a 96 ef 1c
 fa 36 af 9d f8 32 a6 8f dc 7b 35 a9 91 e0 02 c6
 4f 5d 78 33 a5 89 d0 62 07 cc 5b 74 2a 96 ef 1c

method 2 :
 cb 9e 1c 96 05 cc a7 35 5f da 50 33 56 c4 8e 6d
 87 55 3c 76 a5 2f 4a 21 a3 26 b5 df 5a d0 b3 d6
 44 0e ed 04 ce ac c7 92 78 ab 3e 7c b6 e5 6f 8a
 60 e3 69 fb 2e 4c 27 b5 dc 57 c5 8c 66 f5 1f 9a
 11 f3 16 84 4e 2c 47 15 fc 36 65 ef 0a e0 63 e9
 7b ae cc a7 32 58 cb a1 20 a2 29 bb ee 0d e7 72
 98 0b e1 63 e6 74 9f 1d 94 7e bc f7 22 a8 3a 71
 90 72 99 0b e1 60 e2 69 fb 2e 4c 27 b5 dc 56 c5
 8f 6a 80 42 09 db 4e 2c 46 15 ff 3a 70 93 79 a8
 3a 71 93 76 a4 2e 4d 27 b2 d9 4b 1e 9d 17 82 49
 1b 8e 6c 87 55 3f 7a b0 d3 b9 eb 7e bc f7 25 ac
 c6 94 7f ba f0 13 f9 28 bb f1 10 f2 19 88 5a d0
 b2 d9 4b 1e 9c 16 85 4f 2d 44 0f ed 07 d2 b8 eb
 01 c3 86 54 3f 7d b4 de 5d d7 42 09 db 4e 2c 47
 12 f8 2b 41 00 c2 89 5b ce ac c7 92 79 ab c1 83
 46 14 ff 3a 70 93 76 a4 2f 4d 24 ae cd a7 32 59

Both functions are extremely simple, have no setup cost
and require very little internal state (4 bytes) :

mask_string_v1(char *string, unsigned int mask)
{
	while (*string) {
		*string++ ^= mask;
		mask = (mask << 1) | (mask >> 31);
	}
}

mask_string_v2(char *string, unsigned int mask)
{
	while (*string) {
		*string ^= mask;
		mask = (mask << 1) + (mask >> 31) + (unsigned char)*string++;
	}
}

Granted they're not cryptographically strong for anything, but at
least they're offering a masking that does not let the text's author
guess how bytes will be mangled. Especially the second one is
interesting because the mangling changes for every byte.

The real advantage I see is that we only need to hold the 32-bit
mask, and there is no setup cost at all. Would you object against
something like this for this specific usage ?

Willy

/*
  Complete example to encode/decode below, just performs one read() for
  simplicity, so will likely require a single write() or reading from a
  file.

  Outputs generated using :
  $ for ((i=0; i<100; i++)); do echo "GET /"; done > 100get.txt
  $ < 100get.txt ./xormask $RANDOM | od -An -tx1
*/

#include <stdio.h>
#include <string.h>

void mask_string(char *string, unsigned int mask, int len)
{
	while (len--) {
		*string ^= mask;
		mask = (mask << 1) + (mask >> 31) + (unsigned char)*string++;
	}
}

void unmask_string(char *string, unsigned int mask, int len)
{
	unsigned char c;

	while (len--) {
		c = *string;
		*string++ ^= mask;
		mask = (mask << 1) + (mask >> 31) + c;
	}
}

int main(int argc, char **argv)
{
	char buf[1024];
	int len;

	len = read(0, buf, sizeof(buf) - 1);
	buf[sizeof(buf)-1] = 0;
	mask_string(buf, strtoul(argv[1], NULL, 0), len);
	unmask_string(buf, strtoul(argv[1], NULL, 0), len);
	write(1, buf, len);
	return 0;
}

Regards,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 7 Jan 2011 17:32:53 -0800

> the balance of risks vs costs in some situations :-/

I guess we will have to agree to disagree.

No. 

Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 8 Jan 2011 02:50:02 +0100

> I guess we will have to agree to disagree.

Indeed. I don't see any other possible issue then. I will have tried to
propose some solutions in relation with estimated risks, and you will
have expressed your high expectations. I just have no idea why you
absolutely want to ensure that we could safely saturate a network link
for as long as the age of the universe without risking to see a request
which we will still see anyway, all that to protect against some proxies
that might have a sloppy request parser. Clearly that's beyond my
understanding, I'm just hoping someone else will understand what it
brings.

Willy

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 7 Jan 2011 18:08:53 -0800

You haven't said anything new here do I think we are officially done

Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 8 Jan 2011 09:12:32 +0100

> You haven't said anything new here do I think we are officially done

If you want, we can say that : I officially object to the cost of your
proposal given that it relies on pure guess and not a quantification
of the risk, and it is easily provable that it is overkill for the
simplest requests we have to care about (eg: "GET /\n", 48-bit long).

Willy

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 8 Jan 2011 06:57:49 -0800

> simplest requests we have to care about (eg: "GET /\n", 48-bit long).

You have proven no such thing.

-Ekr

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 8 Jan 2011 07:09:07 -0800

Or more properly, you have not proven that there is no risk, but rather that
there is no risk, but merely chosen a particular attack. To repeat myself
for
the umpteenth time, an attacker can use a sliding mask to produce a message
with a particular structure. They cannot do that with a generated (CTR or
HMAC)
solution. No, I do not have an attack, but indistinguishability from random
is stronger than not.

As for your "official" objection, yes, yes, I know you object. Making it
"official"
doesn't somehow change anything.

Chairs; I think it's clear that we're long past anything that is new being
said here.

Can you please run a straw poll to resolve the question of masking. IMO the
relevant options are:

0. No masking.
1. A short fixed mask carried entirely in the packet.
2. A longish repeated mask computed from the packet. For concreteness,
suppose
    HMAC-SHA1(<uuid>, <server-conn-key> || <client-conn-key> ||
<packet-key>), but
    obviously there's flexibility here.
3. A fully generated mask, e.g., using AES-CTR or HMAC-SHA for each byte.

-Ekr

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 8 Jan 2011 07:10:03 -0800

On Sat, Jan 8, 2011 at 7:09 AM, Eric Rescorla <[email-masked]> wrote:

> there is no risk, but merely chosen a particular attack.
>

Gah. "That there is no risk of a particular chosen attack."

> To repeat myself for

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 8 Jan 2011 16:23:53 +0100

> You have proven no such thing.

Sending 2^48 different patterns on the wire, how ever they're mangled
will make your desired 48-bit pattern appear. Using keys smaller than
the pattern may help the attacker establish a relation which helps him
send less than 2^48 patterns, but using larger keys will not prevent
one 48-bit pattern from appearing in a series of 2^48 random-looking
different patterns.

You could even send /dev/random to the wire if you want. At one point
you will find "GET /\n", and you know that.

Also, I'd like to state that it's important to define what we're trying
to achieve. It has been speculated that some intermediaries might skip
non-HTTP looking garbage and automatically resync on what looks like
HTTP. That probably means that those intermediaries will automatically
consider a pattern starting as "GET " as a new request ?

If so it will appear every 2^32 32-bit message, or every 16 GB in a
random stream. Why use 160-bit cryptographically strong ciphers to
generate better random when 32 bits of those random will be enough to
get the faulty component to resync ?

It would be nice if you could for once defend your points based on
*facts* and not intimate feelings. All we know is that I have proven
nothing, but that's for sure considering that you're asking me to prove
that we can remain protected against a risk we cannot even reliably
describe !

If the components you're talking about exist, what allows you to think
that by sending random garbage when they're expecting a valid HTTP request,
you won't make them seek past the end of their request buffer, to a point
that it cleanly syncs on another request buffer which contains a valid
HTTP request ? How could you prove that it cannot happen ? That's a real
risk for a component which is able to do complex things such as skipping
over random data looking for a valid HTTP request, when the required
behaviour is a lot simpler to implement.

Willy

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 8 Jan 2011 16:31:47 +0100

> Chairs; I think it's clear that we're long past anything that is new being

You're exagerating Eric. I have provided code, examples and performance
measurements to make progress. You desperately remained on your position
without any *fact* to explain it.

> 1. A short fixed mask carried entirely in the packet.

1.5. A short sliding mask derived from a short one carried in the
     frame and which does not require many CPU cycles per frame.

> 3. A fully generated mask, e.g., using AES-CTR or HMAC-SHA for each byte.

We should clarify one important point as well :
1. mask framing headers
2. mask payload only

Regards,
Willy

---

From: Cedric Vivier <[email-masked]>
Date: Sat, 8 Jan 2011 23:40:12 +0800

> you will find "GET /\n", and you know that.

This might be a stupid idea but wouldn't fragmenting the frame at
every "HTTP/" [1] occurence within a message guarantee that no broken
proxy would ever interpret any 'request' ?

Eg:
0x04 0x0F "GET / HTTP/1.1"

becomes :

0x84 0x06 "GET / "
0x04 0x08 "HTTP/1.1"

(maybe it would need an IMPLICIT_MORE bit rather than already spec'ed MORE bit)

Looks much simpler to implement as part of WebSocket's data framing on
the client and still allows servers to use sendfile or similar as they
see fit.
Sorry for the noise if I'm completely off-track :-)

Regards,

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 8 Jan 2011 17:00:46 +0100

Hello Cedric,

> Sorry for the noise if I'm completely off-track :-)

No you're not off-track and it's a really good idea. In my opinion it
is hard for the sender to ensure it does that for specific strings,
however we could very well decide that frames emitted by a browser
must not be larger than XXX bytes (eg: 4 or 8 bytes). That way we'll
have two bytes of framing everywhere in the middle of requests. And
that does not even require complex changes at all. For instance,
preventing the browser from sending frames larger than 8 bytes will
imply a 25% size overhead for frames larger than 8 bytes, which is
equivalent to sending a 32-bit key with a 16-bytes frame.

Possibly that can be studied.

Thanks,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 8 Jan 2011 08:03:31 -0800

> without any *fact* to explain it.
Yeah, whatever.

-Ekr

---

From: Andy Green <[email-masked]>
Date: Sat, 08 Jan 2011 16:13:42 +0000

> to achieve. It has been speculated that some intermediaries might skip

Yeah that might be a good idea.  But, maybe I missed the "point".

-Andy

---

From: Pieter Hintjens <[email-masked]>
Date: Sat, 8 Jan 2011 17:20:01 +0100

>     frame and which does not require many CPU cycles per frame.

+1 until specific issues are raised with it that can be solved reasonably.

Willy, I appreciated the running code.

-Pieter

---

From: Andy Green <[email-masked]>
Date: Sat, 08 Jan 2011 16:20:49 +0000

> No you're not off-track and it's a really good idea. In my opinion it

Making HTTP/ unspeakable sounds a lot more lightweight and deterministic 
to me too than some terrifically high bar of obfuscation crypto defined 
by some particular dude "just because".

-Andy

---

From: "Pat McManus @Mozilla" <[email-masked]>
Date: Sat, 08 Jan 2011 12:04:01 -0500

On Sat, 2011-01-08 at 16:20 +0000, Andy Green wrote:
>  defined 

You are being unfair to Eric and his substantive contributions to both
this group, this discussion, and the Internet community.

That being said, I haven't yet heard anything that makes me concerned
that an attacker can "produce a messasge with a particular structure"
using an inexpensive sliding mask. It appears that that concern falls
outside the class of attacks we should realistically be worrying about
which is the attacker generating specific byte sequences of her
choosing.

I'm interested in hearing any arguments that advance my understanding of
the risk of such a simple mask beyond "it allows the attacker to produce
non-random (but also non-controllable) bytes". What is the relationship
here that leads us down a dangerous looking path? If I've missed them in
the recent torrent of dialogue, I apologize in advance and appreciate
the pointers.

-Pat

-- 
http://www.getfirefox.com/

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 8 Jan 2011 09:31:39 -0800

> the recent torrent of dialogue, I apologize in advance and appreciate

Hi Patrick,

I don't really have anything that I expect to be convincing to the
non-paranoid.
The attack vector  (if there is any) is as you say: an attacker can
control the bytes
so that they are non-random, but only partly controllable (i.e., they
can guarantee
any chosen relationship between two bytes masklen apart). I don't have
an attack that
actually exploits this, it just gives me a bad feeling: in the
security community we try
to design stuff that is secure with only very weak assumptions about
the threat model
and it seems clear that indistinguishability requires weaker
assumptions, so all else
being equal, that seems like a better choice.

Now, obviously all else isn't equal, and if there is a major objection
to stronger masking,
then that should override my (and others, I would note) icky feelings
about weak masking.

However, the only argument against stronger masking that I'm aware of,
namely that it has
a performance cost, seems to me to be extremely weak in view not only
of the performance of
existing machines and of the expected increase in performance in the
future. So on balance
I continue to favor stronger masking. However, I can certainly
understand how others would
feel differently.

-Ekr

---

From: Andy Green <[email-masked]>
Date: Sat, 08 Jan 2011 17:35:27 +0000

> this group, this discussion, and the Internet community.

Hey, thanks for alerting me to how unfair you think I am being.  If you 
could provide any evidence about why what I said is unfair other than 
just announcing your opinion out of the blue, that would be even more 
awesome.

I base what I am saying on what I read on this list, where Willy seems 
to be sending out facts and code and Eric is sending out "whatever".

> which is the attacker generating specific byte sequences of her

As I have said several times, I do not believe the case has been made we 
should care about even that; IMO we should wash our hands of these 
alleged broken intermediaries because there is no end to it.

Don't forget this is in a context where it can only be an intermediary 
targeted, and one that is broken in specific ways that is claimed to 
exist only after one unrepeatable -- Pons and Fleischmann style -- test.

> I'm interested in hearing any arguments that advance my understanding of

How about you turn your intellect to Cedric Vivier's novel suggestion to 
simply disallow "HTTP/" in websocket packets as well as the "political 
mainstream" masking and announce your thoughts on that.

-Andy

---

From: Cedric Vivier <[email-masked]>
Date: Sun, 9 Jan 2011 02:01:24 +0800

On Sun, Jan 9, 2011 at 01:04, Pat McManus @Mozilla <[email-masked]> wrote:
> non-random (but also non-controllable) bytes".

Considering an attacker could control of both the JavaScript
application and the WebSocket server (ie. a malicious website rather
than a XSS), simple masking certainly feels a fragile protection
against a determined attacker and I share Eric's concerns about it.

On top of this, even simple inexpensive masking significantly limits
potential efficiency of WebSocket servers as it makes any payload
essentially uncacheable therefore blocks usage of efficient and
scalable zero-copy mechanisms (sendfile/splice/tee/..) that are used
in modern HTTP servers.

Fragmenting messages containing "HTTP/" or, even simpler, inserting a
'break' byte every 8 bytes of the payload, seems like a simple and
minimum overhead way to guarantee an attacker cannot send out bytes
that would look like a request, while keeping the payload zero-copy
friendly for servers.

Regards,

---

From: Salvatore Loreto <[email-masked]>
Date: Sat, 8 Jan 2011 19:18:54 +0100

On 1/8/11 4:09 PM, Eric Rescorla wrote:
> there is no risk, but merely chosen a particular attack. To repeat 
> myself for
> with a particular structure. They cannot do that with a generated (CTR 
> or HMAC)
> As for your "official" objection, yes, yes, I know you object. Making 
> it "official"
> Chairs; I think it's clear that we're long past anything that is new 
> being said here.
>
(as co-chair)

there is already a clear consensus about masking from the straw poll 
ended yesterday
so "No masking" is not a possibility for a new poll.

The straw poll ended yesterday has showed a great consensus about the
GET+Upgrade+Masking approach
with mandatory masking from client to server

of course all the details about how it will play out are already agreed.
So we will consider the possibility to run a poll to resolve the 
question of masking.

cheers
/Sal

---

From: Salvatore Loreto <[email-masked]>
Date: Sat, 8 Jan 2011 19:20:56 +0100

> of course all the details about how it will play out are already agreed.
I meant

"all the details about how it will play out are not yet decided neither 
agreed"

-- 
Salvatore Loreto
www.sloreto.com

---

From: "Pat McManus @Mozilla" <[email-masked]>
Date: Sat, 08 Jan 2011 13:21:31 -0500

Hi Cedric,

> against a determined attacker and I share Eric's concerns about it.

"feels fragile" doesn't resonate with me in this context on its own
without more reasoning. I'm not speaking for anyone else.

> scalable zero-copy mechanisms (sendfile/splice/tee/..) that are used

In order to mitigate this the masking is applied unidirectionally from
client toward the server. The client is unlikely to have the kind of
data that benefits from zero copy (i.e. in page cache sent to multiple
recipients) and in any event is much less likely to have highly scalable
workloads where the copy-based IO is super relevant. 

A compromised server can already send whatever bytes it wants in the
server->client direction. The mask prevents the server from generating
bytes that travel from client to server and potentially cross an
intermediary along the way.

> that would look like a request, while keeping the payload zero-copy

in general I don't like the complexity of things that have to statefully
scan, pad to different lengths, and fragment payloads. Lots of state and
branching in the algorithm and in turn it only addresses a particular
attack rather than a category of attack. I don't see an advantage over a
simple cheap-per-message XOR.

-Pat

---

From: John Tamplin <[email-masked]>
Date: Sat, 8 Jan 2011 13:27:44 -0500

> that would look like a request, while keeping the payload zero-copy

I am not sure zero-copy of 8 byte payloads is something to count as an
advantage, and it also seems unlikely the client is going to benefit
from zero-copy sends anyway (as an example, many browsers store the
text internally as UTF16 so it already has to be converted to UTF8
before sending in a text frame -- it is easy to just do the XOR as you
build that frame).  Also, this feels very fragile -- do you also split
on "http/", "Http/", etc for ones that might interpret it in a case
insensitive manner?

Finally, from an implementation point of view, this seems far more
complicated than a simple XOR and the extra branches are likely to be
slower than in-register math if you are counting down to that level.

---

From: Bruce Atherton <[email-masked]>
Date: Sat, 08 Jan 2011 10:33:41 -0800

On 07/01/2011 3:15 AM, Dave Cridland wrote:
>
> Would the working group consider masking in this parallel universe? Of 
> course not, because that would be silly.

I disagree. I think an argument can be made for masking even in the 
absence of a known attack. Call me silly if you want to.

The simple fact is that there have been a number of protocols introduced 
over the years where attacks have been developed that were never 
envisioned by the designers of the specs. I think you can assume the 
same thing will happen with Websockets, no matter how careful the WG is.

But we can see in hindsight that had attackers not been able to control 
the bits on the wire, a huge class of attacks would not have been 
possible. Not all attacks, mind you, but a large number.

So it is not unreasonable for people to say now, with this new protocol, 
let us stop attackers from controlling bits on the wire as much as we 
can. It may never prove to be beneficial, but experience shows us that 
it is likely to be.

The question is how much are we willing to pay for a benefit that we 
can't quantify and that may never appear. Hopefully, if there were no 
cost at all to masking you would not have an issue with it. As the cost 
goes up, we start seeing more and more people decide that the price is 
too high for a risk that is so nebulous. So there is a real incentive to 
keeeping the cost of masking low, to me.

The other question is whether we can eliminate that cost altogether in 
situations where we can guarantee via other means that attackers are not 
controlling the bits.

>
>  intermediaries that are already vulnerable to attacks of the form 
> we're trying to protect against by using Flash or Java.

I keep seeing comparisons of Websockets to Flash and Java. These are not 
even close to being the same situation.

Browser vendors do not develop Flash or Java plugins. They do not ship 
with them. Many environments forbid the installation of any plugins for 
exactly the reason that Flash and Java are security risks. When a user 
installs the plugin, they have to take responsibility for doing so, and 
any bugs or security issues are directed to Adobe or Oracle or whoever 
developed the plugin.

Websockets is different. Websockets is going to be part of the browser. 
The browser vendors are going to ship their own code. That means that 
they are responsible for Websockets, as they are not responsible for 
Flash and Java. It also means that browsers will always have an 
implementation of Websockets installed in all environments, including 
the ones that don't allow plugins (although they may be configured to 
turn it off).

> used rich content technologies of today.

That seems to be false given that they haven't been fixed to date. I 
doubt that any browser vendor wants to take the risk and assume they 
will be fixed, only to see themselves labeled "Insecure" by people who 
don't understand where the real security vulnerability was.

This is a known vulnerability. No major browser vendor is going to ship 
a Websockets implementation that is exposed to it. They have all said so 
on this list. Let's move on.

---

From: Cedric Vivier <[email-masked]>
Date: Sun, 9 Jan 2011 02:40:46 +0800

On Sun, Jan 9, 2011 at 02:27, John Tamplin <[email-masked]> wrote:
> build that frame).

Indeed. I assumed the masking was bi-directional, so a simple
fragmentation or byte insertion would have still kept the payload
easily cacheable on the server after preprocessing once (later send
the whole-length cached preload in one 'zero-copy call').

Now that masking is clarified to be for client-to-server direction
only, the concern regarding above use case is moot.

Regards,

---

From: Bruce Atherton <[email-masked]>
Date: Sat, 08 Jan 2011 11:00:21 -0800

On 06/01/2011 9:47 PM, Eric Rescorla wrote:
> Really? That's not the behavior I'm familar of with chat systems, 
> where things

Why are you claiming to know all the ways a protocol that hasn't even 
been released yet is going to be used? How many bytes long will Google 
Wave Websocket messages be 5 years from now? Or Suggest? Or any of a 
million other examples, including a bunch that will only be invented if 
Websockets is lean enough to allow them to exist.

Bulking things up because current usage doesn't allow for the kinds of 
applications and message sizes that Willy is talking about is pretty 
shortsighted.

---

From: Andy Green <[email-masked]>
Date: Sat, 08 Jan 2011 19:39:53 +0000

> can. It may never prove to be beneficial, but experience shows us that

Sure that this is not unreasonable?  Don't forget a websocket connection 
that the client can send something on has had to go through the initial 
handshake dance proving it is talking to a willing partner.  It means 
you can't just spray packets around the internet already; it's a very 
very narrow attack path for sure, not a generic one.

Therefore all this brow-furrowing about what is, if anything, needed in 
addition to be "nice to the internet" is restricted to unidentified 
intermediaries broken in a specific way inbetween a client and a real 
websocket server -- everyone on every side of the debate is willing to 
concede that AFAIK.

> on this list. Let's move on.

Actually handwaving that it is a "known vulnerability" over-eggs the 
pudding.  It is very much an unknown and unreproducible alleged 
vulnerability in software that has not been identified publicly (or 
AFAIK privately) and may be a byproduct of the interpretation of the 
testing action.  Nobody seems to want to "out" these alleged broken 
intermediaries as part of the protocol either.

Nor is Websockets "exposed" to this alleged vuln as you say, it is 
claimed it is part of the attack vector, along with wget, curl, nc, 
anything else you can open a socket connection with.

-Andy

---

From: Greg Wilkins <[email-masked]>
Date: Sat, 8 Jan 2011 21:07:06 +0100

> with mandatory masking from client to server

Sal,

I certainly did not vote for mandatory masking!

The straw poll I voted for was only "upgrade-with-unidirectional-xor-mask"
No mention of mandatory and certainly no mention of strong masking
that makes the payload totally random.

regards

---

From: Greg Wilkins <[email-masked]>
Date: Sat, 8 Jan 2011 21:10:00 +0100

+1

---

From: Salvatore Loreto <[email-masked]>
Date: Sat, 8 Jan 2011 21:22:58 +0100

On 1/8/11 9:07 PM, Greg Wilkins wrote:
> On 8 January 2011 19:18, Salvatore Loreto<[email-masked]>  wrote:
as I said in the mails there are still details that need to be agreed.

one is what mandatory means!
the John proposal 
(http://www.ietf.org/mail-archive/web/hybi/current/msg05559.html)
seems to be a possible compromise we can work on

> that makes the payload totally random.
what kind of masking and how strong it has to be is another point yet to 
be discussed/agreed

cheers
/Sal

-- 
Salvatore Loreto
www.sloreto.com

---

From: Bruce Atherton <[email-masked]>
Date: Sat, 08 Jan 2011 14:04:30 -0800

On 07/01/2011 1:19 PM, Eric Rescorla wrote:
>
> My objective is to make the bits that appear on the wire 
> indistinguishable from random
> available, and the method I proposed does that.

It is true that your goal is clear, but I don't understand why you think 
this goal is necessary.

The specification already allows for two forms of Websocket, a simple 
one denoted by the scheme "ws:" and a secure one denoted with "wss:". 
The latter one will have the random byte stream characteristics you are 
interested in. If you are uncomfortable with any other kind of stream, 
make sure your client only supports secure Websockets.

The reason for the division between the two types is that in some 
situations, people want the ability to trade-off some security for lower 
cost. This cost is not just in terms of machine processing, but other 
things as well. For example, the decreased cost of debugging streams of 
data when they are decipherable with a tool like Wireshark. Keeping 
masking simple decreases a bunch of costs in ways that matter enough to 
people that they are willing to support two separate websocket schemes 
in order to have that choice.

Or perhaps you are actually arguing that your masking should be the 
mechanism for the wss: scheme? Or that there should be no ws: scheme for 
anyone?

---

From: Bjoern Hoehrmann <[email-masked]>
Date: Sat, 08 Jan 2011 23:38:36 +0100

>the recent torrent of dialogue, I apologize in advance and appreciate

(I wish someone'd thought of asking this before another 100+ thread...)

Well, if you take my simple straw man (prefix a mask, xor the following
bytes with it, repeating the mask as necessary) then you simple need to
arrange the traffic in a manner that keeps the connection alive and send
a lot of data; eventually you get the attack payload you want on the
wire. If a proxy listening in on the connection somehow manages to skip
over all the rubbish and then takes up your attack payload and then does
something dangerous with it, then your attack has succeeded.

The only questions are whether such proxies are deployed in quantities
and configurations that should have us worried (there is no evidence at
all that there is a proxy that has the relevant combination of flaws)
and how much data you have to make the browser put on the wire.

You most likely don't need exactly one out of n keys for an attack to
succeed as you have some tolerances like case-insensitive protocol ele-
ments, and you can do some things to cleverly arrange the bytes you ask
the browser to mask and send, or for that matter you can make the pay-
load very large so many keys would work (if the key is just a byte you
simply generate all 256 masked payloads).

One could look at this by comparing it to another threat. There are for
sure intermediaries that have an integer overflow vulnerability with
requests that are longer than 2 or 4 GB, so if an attacker can make a
HTTP client send a very large crafted payload, an intermediary might
take part of the payload as second HTTP request. Should that mean all
HTTP clients that send untrusted data must limit the size to 2 GB, or
at least heavily encrypt data that is longer?

Earlier we talked about using a WEBSOCKET method in the handshake, and
Adam Barth reminded us that as far as cross-protocol attacks go, that's
a problem because sending "W" at the beginning hasn't been studied. So
should that mean over at the W3C "CORS" cannot use "OPTIONS" to verfiy
certain requests are welcome because "O" hasn't been studied there?

We haven't learned about any new attacks from Adam et al.'s paper, the
cache poisoning issue has been known since at least 2005 with request
smuggling attacks (fill in a couple of newlines in some XHR header and
the proxy sees two requests where the browser thought it's sending one)
and the host misdirection attack has been known since at least 2008, it
is even mentioned in the Wikipedia article on transparent proxies since
2009 and Roy T. Fielding and Jeff Hodges posted links to Robert Auger's
paper to the list in 2009, and the paper also discusses the cache issue.

Hasn't stopped Flash and Java plugin vendors from allowing attackers to
exploit these issues, hasn't stopped browser vendors from allowing the
plugins to run in their software, hasn't stopped Websocket drafts from
being adopted in browsers. Again, immediately after this list has been
created, Roy T. Fielding noted that an Upgrade handshake succeeding does
not mean intermediaries won't mistake further traffic as HTTP traffic.

I've been reading this whole discussion as an attempt to find something
that's simple and efficient with reasonably low risk. Robustness is the
last requirement in our requirements document with a lowercase "should".
You can't make any and all servers and intermediaries stop treating
traffic as HTTP traffic by sending a couple of magic bits. Water is wet.
Seriously, if browser vendors required a zero-risk design where the zero
is easy to prove, they should have shot down any and all proposals that
do not meet that requirement immediately instead of implementing drafts
that very obviously don't meet that requirement.

So with the masking straw man above the concern is essentially about a
proxy that has never been seen or heard of being vulnerable to attacks
we don't quite know how to make feasible. I can understand some worry
that this very simple scheme is insufficient, but going from there to
"the mask must include a client nonce, must include a server nonce,
must include some special secret, must include a block counter, must
include a per-frame key, the frame key must at least be 4 bytes long,
all the key material must be passed through HMAC-SHA1, the header must
be masked, any and all Websocket clients must mask always, ideally put
some CONNECT talisman ahead on the connection" and probably things I've
missed, is a very very long way.

Obviously I am not entirely comfortable with a scheme this simple, or
I would not keep calling it a straw man, but among all the proposals
we've had, it does seem to meet the many conflicting requirements best,
and, unlike the super duper double plus plus extra robust scheme, it's
somewhat consistent with how we got here.

It also seems wrong to look at this solely from the bits-on-the-wire
perspective. Browsers regularily check the web for browser updates and
anti-phising lists and whatnot, they could do sanity checks whether the
user is behind a vulnerably proxy. They also have XSS filters to check
for seemingly dangerous patterns, they could simply pre-scan the masked
frame, if it could be mistaken for a HTTP request, pick a different
key, if that fails, split the message into multiple frames, or whatever.

"If masked payload contains case-insensitively 'Host' regardless of the
key chosen, split message at after each 'Ho' into two frames".

You now need the previous miracle proxy we don't know exists and an
attack we don't know how to make feasible and also some additional proxy
bug that allows you to do dangerous things without "Host", at the cost
of rare failures because whatever key is applied doesn't prevent "Host",
and the server assumed the message would arrive as one frame but did
not. Add whatever additional bad words you care about, say "http", or
make the patterns a bit more complex to avoid the odd maybe-failure,
checking for a double newline somewhere after "Host" for instance. I'm
sure of course that's unacceptable, just like all the other proposals.
-- 
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: Willy Tarreau <[email-masked]>
Date: Sat, 8 Jan 2011 23:40:32 +0100

> seems to be a possible compromise we can work on

I noticed this proposal, it looks like a nice starting point, as
well as Greg's reply who reminded his close proposal to help merging
the two threads.

  http://www.ietf.org/mail-archive/web/hybi/current/msg05589.html

Since I've not seen any progress after that, and the last poll is over,
I think that it could be a good opportunity to try to merge them both.

One difference I'm seeing that we should get rid of to start more easily
is that John's proposal already names the masking type, and Greg already
suggests a fixed length masking key.
  => we could for now consider "the masking type" and "its key of the
     adequate length for the masking type". This will make it easier to
     focus on the general principle of using the extensions for that.

Among the comments I have on the proposals, I still think we should
use one of the reserved bit to indicate presence of extensions or not,
for the day we want to support multiplexing. Otherwise, and old version
intermediary might get the framing wrong if it can't detect presence of
extensions nor know their length (or maybe we could have the payload
len cover the extension data, though that would probably be harder to
implement for clients). It could also make it possible to strongly
mask some frames (eg: login/passwd). I'm not saying the reserved bit
is enough, but rather that it can help decide how to handle extensions
when some frames use them and others don't.

I find it interesting that both allow some types of communications to
happen without masking, considering that there has been some demand
that some non-browser clients could avoid masking in some situations.
After all, it leaves a choice comparable to how we currently decide
whether to use HTTP or HTTPS for some intra-enterprise communications.

I like the ability to mask some extensions too, though we should be
careful to keep the ability to have some in clear text (eg: support
for NAT by some dumb equipments of addresses sent in extension data).
Maybe the order of the extensions is enough for that.

Regards,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 8 Jan 2011 16:00:29 -0800

On Sat, Jan 8, 2011 at 2:04 PM, Bruce Atherton <[email-masked]> wrote:
> The specification already allows for two forms of Websocket, a simple one
> denoted by the scheme "ws:" and a secure one denoted with "wss:". The latter
> one will have the random byte stream characteristics you are interested in.
> If you are uncomfortable with any other kind of stream, make sure your
> client only supports secure Websockets.

Regrettably, this is not the case except for certain specific ciphers
(in particular
block cipher in CBC mode.) It's not at all the case for RC4 and only
the case for
some CTR mode implementations.

Best,
-Ekr

---

From: Bruce Atherton <[email-masked]>
Date: Sat, 08 Jan 2011 16:13:06 -0800

On 08/01/2011 11:39 AM, Andy Green wrote:
> testing action.

As others have suggested, feel free to try to convince the browser 
vendors of that. But please do it off-list, as it has been tried on list 
many times without success and it is getting tedious to wade through. 
When you have convinced them, come back and let us know.

>   Nobody seems to want to "out" these alleged broken intermediaries as 
> part of the protocol either.
>

They are already "out" through all the other ways they can be accessed 
on the net. I don't see why making Websockets able to exploit the 
defects would have any more effect.

> anything else you can open a socket connection with.

This comment suggests to me that you are still not understanding the 
reason that masking has been suggested. No one has ever claimed it could 
stop an attacker putting malicious bits into a Websocket connection. It 
is intended to stop them from doing it from within a browser. Browser 
vendors do not ship wget, curl, or anything that opens a raw socket.

---

From: Andy Green <[email-masked]>
Date: Sun, 09 Jan 2011 11:51:33 +0000

>>> This is a known vulnerability. No major browser vendor is going
 >>> to ship a Websockets implementation that is exposed to it.
 >>> They have all said so on this list. Let's move on.

> vendors of that. But please do it off-list, as it has been tried on list

Bruce, you are the guy who handwaved about "known vulnerability" on the 
list so it is you I replied to on the list.

I agree it is tiresome to keep posting reality-based corrections when 
the centre of gravity of the group doesn't care and is off agreeing 
something completely different.

> vendors do not ship wget, curl, or anything that opens a raw socket.

What you wrote is incorrect, websockets is not exposed to any 
vulnerability (I added your quote back in at the top).

The reason I don't bother engaging with what you think is the reason for 
munging, is that the error in logic leading to people thinking that 
munging does anything useful occurred a step or two back: when they 
accepted that fighting troll / ghost / alleged broken intermediaries was 
the problem of websocket protocol to fix, when they can't even point at 
one and the intermediaries remain exposed until they get updated 
themselves.  Even that they might ever exist is the problem that must be 
solved now by munging.

The browser guys now need some figleaf to explain why they revert their 
security taint on websockets and munging fits the bill perfectly, so 
they will just sit until munging comes.  Sure!

-Andy

---

From: Julian Reschke <[email-masked]>
Date: Sun, 09 Jan 2011 13:06:09 +0100

> they will just sit until munging comes. Sure!

One thing I'd like to understand is why Apple and Chrome haven't stopped 
shipping browsers with the -00 protocol enabled by default. One could 
think the problem isn't nearly as serious it seems.

Best regards, Julian

---

From: Maciej Stachowiak <[email-masked]>
Date: Sun, 09 Jan 2011 04:48:01 -0800

On Jan 9, 2011, at 4:06 AM, Julian Reschke wrote:

> One thing I'd like to understand is why Apple and Chrome haven't stopped shipping browsers with the -00 protocol enabled by default. One could think the problem isn't nearly as serious it seems.

Our thinking so far is that the problem is severe enough that it should be addressed in the protocol design, since the protocol is not yet final, but not (at this time) severe enough to merit an emergency security update. The bar for security in a brand new protocol should be much higher than just "shouldn't be so bad that vendors will spin security updates just to disable it".

Regards,
Maciej

---

From: Greg Wilkins <[email-masked]>
Date: Sun, 9 Jan 2011 13:51:31 +0100

On 9 January 2011 12:51, Andy Green <[email-masked]> wrote:
> security taint on websockets and munging fits the bill perfectly, so they
> will just sit until munging comes.  Sure!

Andy,

I think that is a slightly unfair characterisation of why a consensus
has formed around masking.

I'm as dubious as any that WS enables any exploits against any real
deployed browsers with the cache poisoning vulnerability.   The reason
I believe that masking is looked at favourably is that it is not
targeted at a specific known exploit (as CONNECT handshake is), but is
instead targeted at a class of conceivable vulnerabilities that result
from sending arbitrary content in non-HTTP framing through HTTP
intermediaries.

We really need to try to take some of the heat out of this discussion,
so that progress made is not lost.

regards

---

From: Bruce Atherton <[email-masked]>
Date: Sun, 09 Jan 2011 13:16:17 -0800

On 09/01/2011 3:51 AM, Andy Green wrote:
>
> Bruce, you are the guy who handwaved about "known vulnerability" on 
> the list so it is you I replied to on the list.
>

I did say that this is a known vulnerability. I did not say that it is a 
valid vulnerability to worry about. Whether it is or it isn't, I don't 
know and I don't care because what I think doesn't matter in this instance.

I see a lot of people get frustrated on this list because they think 
that the point of the discussion is to present the best technical 
argument. It isn't. The point is to persuade other people about the best 
technical argument. And the people who ship web browsers have all said 
that they are not persuaded by the types of arguments you have presented.

Andy, I can understand your frustration, but it isn't helping anything. 
The decision has been made via the straw poll to use masking in the 
protocol. Let's put this to rest now, please.

---

From: Bruce Atherton <[email-masked]>
Date: Sun, 09 Jan 2011 14:02:36 -0800

Thanks for the correction, but I still don't understand.

If you are suggesting your mask for the wss: scheme in order to provide 
for a stream of apparent random bits on the wire, then that makes 
perfect sense. But for the purposely less-secure unencrypted ws: scheme 
I don't understand why it would be necessary.

On 08/01/2011 4:00 PM, Eric Rescorla wrote:
> On Sat, Jan 8, 2011 at 2:04 PM, Bruce Atherton<[email-masked]>  wrote:

---

From: Eric Rescorla <[email-masked]>
Date: Sun, 9 Jan 2011 14:16:53 -0800

On Sun, Jan 9, 2011 at 2:02 PM, Bruce Atherton <[email-masked]> wrote:
> If you are suggesting your mask for the wss: scheme in order to provide for
> a stream of apparent random bits on the wire, then that makes perfect sense.
> But for the purposely less-secure unencrypted ws: scheme I don't understand
> why it would be necessary.

It's not a matter of random versus non-random. RC4 and AES-CTR without random IV
(which is not a requirement of the standard) provide the attacker with
complete control over
the payload bits on the wire, beause he can predict the keystream.

-Ekr

---

From: Bruce Atherton <[email-masked]>
Date: Sun, 09 Jan 2011 15:46:03 -0800

I apologize if I am being thick, but I still don't understand.

It is my understanding that the masking algorithms which have been 
previously suggested prevent the attacker from controlling the payload 
bits on the wire from within a browser using Websockets without the 
added burden of being cryptographically secure. I had thought that you 
were arguing that the attacker could still control patterns in the bits, 
but not the bits themselves. That seemed like a reasonable thing for the 
ws: scheme to allow, to me, since by design it is a lighter weight, less 
secure form of Websockets and there have never been any exploits that 
relied on that characteristic that anyone has mentioned so far. Now it 
sounds like you are arguing that an attacker can completely control the 
bits no matter what unless it is cryptographically secure.

I'm sure I'm missing something, but I haven't a clue what it is.

---

From: Eric Rescorla <[email-masked]>
Date: Sun, 9 Jan 2011 18:38:05 -0800

What I am saying is that the crypto in tls generally doesn't provide any protection here because absent masking the attacker can produce predictable ciphertext. Maybe that is orthogonal to your point but I thought it was worth noting

Ekr

On Jan 9, 2011, at 15:46, Bruce Atherton <[email-masked]> wrote:

> It is my understanding that the masking algorithms which have been previously suggested prevent the attacker from controlling the payload bits on the wire from within a browser using Websockets without the added burden of being cryptographically secure. I had thought that you were arguing that the attacker could still control patterns in the bits, but not the bits themselves. That seemed like a reasonable thing for the ws: scheme to allow, to me, since by design it is a lighter weight, less secure form of Websockets and there have never been any exploits that relied on that characteristic that anyone has mentioned so far. Now it sounds like you are arguing that an attacker can completely control the bits no matter what unless it is cryptographically secure.
>

---

From: Dave Cridland <[email-masked]>
Date: Mon, 10 Jan 2011 12:37:39 +0000

On Sat Jan  8 18:33:41 2011, Bruce Atherton wrote:
>> Would the working group consider masking in this parallel  
>> universe? Of course not, because that would be silly.
> 
Given you've granted me permission, then, yes. You're being silly.

> The question is how much are we willing to pay for a benefit that  
> we can't quantify and that may never appear. Hopefully, if there  
> were no cost at all to masking you would not have an issue with it.  
> As the cost goes up, we start seeing more and more people decide  
> that the price is too high for a risk that is so nebulous. So there  
> is a real incentive to keeeping the cost of masking low, to me.
> 
> The other question is whether we can eliminate that cost altogether  
> in situations where we can guarantee via other means that attackers  
> are not controlling the bits.
> 
> 
This is all reasonable.

> I keep seeing comparisons of Websockets to Flash and Java. These  
> are not even close to being the same situation.
> 
> Browser vendors do not develop Flash or Java plugins. They do not  
> ship with them. Many environments forbid the installation of any  
> plugins for exactly the reason that Flash and Java are security  
> risks. When a user installs the plugin, they have to take  
> responsibility for doing so, and any bugs or security issues are  
> directed to Adobe or Oracle or whoever developed the plugin.
> 
> Websockets is different. Websockets is going to be part of the  
> browser. The browser vendors are going to ship their own code. That  
> means that they are responsible for Websockets, as they are not  
> responsible for Flash and Java. It also means that browsers will  
> always have an implementation of Websockets installed in all  
> environments, including the ones that don't allow plugins (although  
> they may be configured to turn it off).
> 
> 
What this is saying is that the reasoning for masking is *not*  
technical, but political.

 From a technical standpoint, Flash and Java both allow the attack  
against the intermediaries to be mounted with a far higher degree of  
success.

>> fixed, and not just due to websockets, but due to the far more  
>> widely used rich content technologies of today.
> 
> That seems to be false given that they haven't been fixed to date.  
> I doubt that any browser vendor wants to take the risk and assume  
> they will be fixed, only to see themselves labeled "Insecure" by  
> people who don't understand where the real security vulnerability  
> was.
> 
> 
I think it's far too early to be considered false. It'll only take  
one widely publicised case and a testing tool, and the vast majority  
of intermediaries will be fixed. The widely publicised case is far  
more likely to be Flash based than anything else, too.

> This is a known vulnerability. No major browser vendor is going to  
> ship a Websockets implementation that is exposed to it. They have  
> all said so on this list. Let's move on.

Well, as responsible browser vendors, they could just ship with a  
built-in test tool which checked for a vulnerable intermediary on  
startup and disable WebSockets if one is found - it'd only take a  
couple of seconds to test at worst. But instead they seem to want to  
ship with a truly bizarre overhead of questionable merit.

Since this is no longer a technical argument, I'll refrain from  
attempting to apply technical reasoning, though.

Dave.

---

From: Jamie Lokier <[email-masked]>
Date: Fri, 14 Jan 2011 07:19:47 +0000

Thomson, Martin wrote:
> But since we were talking about pragmatism, we have to expect that
> the probability of an intermediary ignoring noise decreases as the
> amount of noise increases.  You could almost say that the first bytes
> are going to be the most crucial.  But that doesn't help if we're
> heading for an ironclad, provable probability.

So just use lots of short connections and brute-force the first bytes.

Don't forget that an attack can target (say) 10^6 _separate_ users
visiting a page without knowing it has an attack script on it (say
it's a hacked popular server), that they leave open for a day, each
making connections at the maximum rate allowed by the browser.

Suppose browsers are very conservative and permit just 1 new
connection per second in steady state.  (That's probably low.)

That's still 86,400,000,000 connections in a day (roughly 2^36).

It's a lot, but not beyond a well connected site.

If each connection sends just a single 1kB data packet, that's roughly
2^46 bytes a day.  The home users won't notice; it's only 1kB/s.

That's a lot for a site to handle now, but in a few years time, on a
multi-server site, it's plausible that it might not be noticed for a
while, as a hack on the side of someone else's legitimate server
handling large numbers of connections anyway.

That's a pretty big search space in which to find "dangerous strings",
with all the data is concentrated into the first 1kB of each
connection.

Using that, an attack can brute-force their little string into the
first 1kB/s at the rate of 2^46 bytes a day.

Or, if they have to be *initial* bytes (i.e. proper HTTP, no skipping
junk), they can brute-force at the rate of 2^36 a day.

If it's true (and I'm not sure if it is) that case-insensitive "GET\n"
can muddle a certain Apache caching proxy, that's just 2^29 of
entropy, or about *THREE MINUTES* of sustained attack to get a match

Being at the beginning of the data, this might actually be a plausible
attach on Apache caching proxies.

It only needs to get one to successfully poison *someone*'s cache,
which is often enough.

This is with any kind of crypto.  It doesn't matter how "random" the
bits look, if they don't explicitly guard against being recognised as
HTTP.

I doubt there's a real exploit in this, just noting that large numbers
of connections are part of the brute-force possibilities, and this can
attack at the initial bytes.

-- Jamie

---

From: Adam Barth <[email-masked]>
Date: Thu, 13 Jan 2011 23:25:27 -0800

The problem with your analysis is that "GET " isn't actually an
attack.  The cost of constructing an attack string doubles with every
*bit* you add to its length.  If you run your numbers for the attack
string "Willy Tarreau", you'll get vastly different results.

Adam

---

From: Jamie Lokier <[email-masked]>
Date: Fri, 14 Jan 2011 08:09:51 +0000

> string "Willy Tarreau", you'll get vastly different results.

I haven't worked out the numbers exactly in what follows; I am just
too lazy to sum over the variable-length strings etc.  But hopefully
they're in the right sort of range of numbers of bits:

"GET [[:any-valid-URL-characters:]]+\r?\n"

is an HTTP/0.9 request attack requiring roughly 2^40 tries, and

"[ \t\n\r]*[Gg][Ee][Tt][ \t]+[[:any-ASCII-non-whitespace-or-upper-8bit:]]+[ \t]*[\n\r]"

is an attack if the HTTP parser is sloppy (and many are), requiring
roughly 2^36 tries.

Due to not caring about URL and URL length, the attack cost is greatly
decreased compared with looking for a fixed string of similar length.
You can't control the URL you're poisoning, but you have nonetheless
smuggled in a response which you shouldn't.

Due you see a significant mistake in that analysis?

"GET\n" was a reference to the below specifically:

Willy Tarreau wrote:
> On Wed, Jan 12, 2011 at 10:24:33AM -0500, Patrick McManus wrote:
> >
> > >  one 32-bit pattern looking like
> > > and HTTP request for a known proxy (Apache).
> >
> > I don't understand why "GET\n" is interesting in a proxy scenario.
> > Without a host header exactly what host is the server going to be able
> > to spoof in the cache?
>
> The proxy's default host. For example, the hosting provider's site
> or default site. Since it worked on my Apache reverse proxy, I don't
> see why we should dismiss it as a valid case. What Apache does is
> rewrite the request as a complete one with a real Host header.
>
> > The paper that this is all based on discusses
> > mismatches between host headers and ip addresses of the connection.
> >
> > The only thing I can figure is you are saying that a "GET\n" might
> > translate into "GET / HTTP/1.0\r\nhost: previous-request" but that would
> > require inserting the previous request as well.
>
> No, it sets "GET / HTTP/1.1\r\nHost: <default-host>\r\n\r\n".

---

From: Greg Wilkins <[email-masked]>
Date: Fri, 14 Jan 2011 19:15:58 +1100

On 14 January 2011 19:09, Jamie Lokier <[email-masked]> wrote:
> is an HTTP/0.9 request attack requiring roughly 2^40 tries,

For it to be an attack, doesn't it have to be 1.1, or at least 1.0
with a host header?
Unless there is a spoofed host header, then there will be no poisoning
of the cache.

Thus a request that is going to be part of an attack will need to look
something like:

GET /ga.js HTTP/1.1
Host: google-analytics.com

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 14 Jan 2011 09:55:11 +0100

Hi Greg,

> For it to be an attack, doesn't it have to be 1.1, or at least 1.0

Not necessarily, because as I have shown, some intermediaries such as
Apache rewrite "GET\n" as "GET / HTTP/1.1\r\nHost: <default_host>\r\n"
followed by a few headers. Thus this becomes a completely valid HTTP/1.1
request that itself or whatever cache behind it can see.

I'm still thinking we're walking on our own heads anyway, some are trying
to show that a significant amount of crypto can help block supposed attacks
and others are trying to show that some supposedly impossible attacks which
are still possible in some rare situations are not completely defeated by
such protections.

That's why I'd strongly prefer a pragmatic approach :
  - accept that the risk of attack is extremely low and that each attack has
    a cost ;
  - accept a low-cost preventive measure.

If the cost of the protection is lower for normal use than the cost to attack
the service for a specific attacker, it's already a good solution.

Regards,
Willy

---

From: Greg Wilkins <[email-masked]>
Date: Sat, 15 Jan 2011 00:40:55 +1100

> request that itself or whatever cache behind it can see.

wont the default host be valid, and thus not usable in poisoning?

> are still possible in some rare situations are not completely defeated by

true

>  - accept a low-cost preventive measure.

+1 (although I think it is a low-cost mitigation measure, rather than
preventive measure)

cheers

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 14 Jan 2011 18:52:22 +0100

> wont the default host be valid, and thus not usable in poisoning?

If it's valid and the server still controls the response stream, then
we're in the situation we want to avoid.

> +1 (although I think it is a low-cost mitigation measure, rather than

Yes you're right, thanks for correcting me.

Willy