Subject: [hybi] Handshake security proof

From: Paul Colomiets <[email-masked]>
Date: Fri, 17 Dec 2010 00:08:17 +0200

Hi,

Have you considered creating a proof of concept application
in some scripting language that demonstrates behavior
of lazily written intermediary?

Bjoern Hoehrmann have described the laziest parser out there quite well,
this would be a good starting point:
http://www.ietf.org/mail-archive/web/hybi/current/msg05196.html

This application could then be extended to a set of scripts, each of
them to represent behavior of one or several known proxy servers.
As the last step, they can be base for conformance tests for both
protocol specification and it's implementations.

--
Paul

---

From: Bjoern Hoehrmann <[email-masked]>
Date: Mon, 20 Dec 2010 00:42:46 +0100

>protocol specification and it's implementations.

I don't think this is a way forward. At the bare minimum I would say
that HTTP messages have empty lines and sometimes certain things at
the beginning of lines (like header fields) but I also know that's
violated in some HTTP stacks, for instance, I've encountered imple-
mentations that consider the boundary of a message header to be the
first empty line within a buffer .or. at the maximum size of it, say
8192 bytes.

My general assumption is that any design that allows an attacker to
control certain bytes on the wire that does not depend on information
routing failures can be shown to be insecure in some miniscule amount
of cases. And for those that depend on information routing failures
I generally assume that some implementers will find a quick fix for
that failure that turns out to be insecure.

For instance, I would find it quite plausible that someone would up-
date an intermediary that chokes on non-routable hostnames in one of
the CONNECT designs so, say, the non-routable hostname is changed in-
to a routable one on the assumption anything behind that intermediary
can handle that. That then turns out to be an incorrect assumption,
either immediately, or when parts of the backend are changed.

Looking at it from another angle, Robert Auger's "Socket Capable
Browser Plugins Result In Transparent Proxy Abuse" is two years old
now, and we've been discussing these problems for many months on the
list; that apparently hasn't lead to changes in the various browser
plugins and neither did it seem to stop browser vendors to go ahead
releasing their -76 implementations until some people made them a PDF.

Personally, the first thing I usually do in evaluation is applying
something like Occam's razor, roughly, "Going from what is available,
what is required to understand this fully". Take the TLS+nextproto-
neg-only proposal; that has a lot of unknowns (there is a proposal but
no standard, there are patches but no deployment, there is research that
TLS can be made efficient, but implementations aren't) and complicates
other things ("oh let's have TLS without checking certificates") and
is incomplete ("let's use null ciphers! or maybe let's not!").

Another approach is weighing objections. Clearly CONNECT is to create
a tunnel from a client through a proxy to an origin server; clearly
the hosts in the CONNECT request line and the Host header are there to
actually specify the hosts of interest; clearly those protocol elements
are not there to persuade intermediaries to stop looking at what you
are doing on the connections they maintain. Yet that is how CONNECT is
used. So I find objections to CONNECT on those grounds fairly strong.

In contrast, the only objection to proposals for transformations of the
Websocket traffic that prevent an attacker from controlling any bytes
of interest that I've noticed was "doesn't scale" which is rather spe-
cific to individual applications (you have to factor in how you antici-
pate the protocol would be used, which in turn depends on how it is de-
signed), largely unproven (yes, messages might be longer, there may be
more processing required, but it is very unclear if that is an important
factor across the board, and even if it is, by how much), and per-
formance is generally not quite as strong as, say, the combined forces
of security and simplicity.

A third approach would be looking for gaps; for instance, simply sending
two infinite HTTP streams (chunked encoding that does not end until that
is desired) is something that hasn't been studied by the working group.
That isn't excactly simple (the HTTP specification doesn't discuss it in
much detail) and has good objections (intermediaries may have some bad
buffering behavior, might not support chunked encoding from clients),
but ultimately we don't know much about it, as far as list discussions
go.

Another gap is our understanding of the economics of the policies behind
firewall configurations (and as a related matter, software upgrade de-
cisions; how long, and in what quantity, relative to the services that
would be available, would browsers that do not support Websockets be a-
round?). If content and service providers decide they want to push Web-
sockets by offering very cool, very needed things only in environments
that support Websockets, that would be a very different situation from,
say, when everything would be available at comparable quality when Web-
sockets were not available.

We could go on like this forever. It seems to me that TLS+nextprotoneg-
only and what some see as CONNECT-abuse are not viable, and the browser
vendors in the group won't openly support something that has more than,
say, a 1 : 25,000 chance of security vulnerabilities (though they might
go along with it if there is good support behind it) which leaves us
somewhere between Dave Cridland's proposal, conducting research on the
"two infinite streams" proposal, and what I wrote up in five minutes
earlier this week, which is mostly an analylsis of payload masking costs
<http://lists.w3.org/Archives/Public/www-archive/2010Dec/0009.html>, of
which the scenario in my brief analysis is easiest to understand, but
is also the least performant.

What .would. be a step forward would be some data on how important the
various criteria (latency, security, simplicity, and so on) are to the
members of the working group. If preventing intermediary-abuse was not
that important, we could check how widely deployed intermediaries are
doing. If it was exceedingly important, we could rule out proposals
that rely on uncertain assumptions about them. What does research in-
dicate the minimum "ping" times need to be so a chat client can stay
online, and what is the maximum datarate mobile phones can achieve
while not going into a battery-draining mode of transmission? If we
knew these metrics up to some reasonable extent, design would be easy.
-- 
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: Mon, 20 Dec 2010 06:05:47 +0100

Bjoern,

I like your approach, and reading your mail, I got another idea.

> of security and simplicity.

Indeed, there are objections to transformations due to its cost, compared
to, say, sendfile(). However, I'm realizing that we might have two methods
for sending a file, plain text and binary. If we can ensure that the framing
does not contain any CR or LF byte and that the binary mode can only be
enabled after a complete round trip (thus validating the intermediary),
then we could be fine. Basically this round trip would be just an exchange
of capabilities that would prevent both the browser and the server from
emitting CRLFs until the path is validated :

   GET /url HTTP/1.1
   Upgrade: WS
       ----------------------->
                             HTTP/1.1 101
                             Upgrade: WS
                             + 7-bit hello frame to validate the path
       <----------------------
       ----------------------->
   7-bit WS data (or hello frame) to validate the path

       <----------------------> 8-bit permitted now

This would finally result in sort of an upgrade. We would start as HTTP
and require an upgrade from HTTP to 7-bit WS, and when we want to exchange
binary data, we would upgrade from 7-bit WS to 8-bit WS. This upgrade could
very well be announced in the first hello frames if needed. That way we can
have the lowest round trips for normal usage with the security of a CRLF-less
protocol and the ability to exchange binary data without the cost of a big
transformation.

Regards,
Willy

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 20 Dec 2010 10:48:01 +0100

Bjoern,

Nice analysis/summary.

Looking at it through your eyes, it does appear that payload masking
is an approach that is going to unequivocally resolve the intermediary
abuse issue and has the least strong objections.   I have to say that
I've not been keen on masking, but would certainly accept it if others
found it a way forward.

To address to issue of efficiency of masking, why not use a gzip  as
the masking mechanism, since this has been an oft requested feature
anyway.  I understand that with pure gzip, it is probably possible to
invent binary content that will result in known compressed content,
but I'm sure that if we mixed some random salt into the dictionary
(and maybe each frame?), we'd get enough unpredictability (and the
hello frames can exchange the salt).  This way the masking will give
us benefits as well as obfuscating the content.

A GET+Upgrade+Hello+Gzip  approach has:
 + about the same success rate as any other proposal.
 + is safe from intermediary abuse
 + has no additional round trips
 + can be deployed today.

Furthermore, I'd propose that we make the gzip element a WS extension
(in terms of the current framing) and gzip would just be the default.
That way, consenting clients/servers would be free to replace gzip
with other compressing mechanisms, with real encryption or even with
no masking (if the threat of silly intermediaries is known not exist).

cheers

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 20 Dec 2010 11:02:04 +0100

On 20 December 2010 10:48, Greg Wilkins <[email-masked]> wrote:
> To address to issue of efficiency of masking, why not use a gzip
> ...

To expand on this idea of a masking extension a bit more....

I think that initially the browsers should be deployed with only a
single masking extension enabled (let's say gzip+salt, or if that is
not good enough some per frame encryption).

Then large data centres offering WS support, would be able to install
WS connection aggregators/balancers that would terminate the
connections from the browsers and accept the masking extension.  But
these intermediaries would make the connection to the back end servers
without any masking extension, as they are going through a known
environment.   This would allow the application servers to avoid the
need to mask and they could even use sendFile or equivalent mechanisms
to send the content.   It would then be the data centres WS offloaders
job to apply the masking as the data is sent to the browsers.

Simple deployments would not need to bother with this complexity, and
browsers could talk directly to servers with gzip+salt masking.

The cool thing about this approach is that we create a market place
for intermediary vendors to innovate with efficient WS
aggregators/balancers that will offload the masking effort from
application servers. Meanwhile, the browser vendors have a simple
story of accepting only 1 extension: gzip+salt (and they may in time
accept others).

cheers

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 20 Dec 2010 11:38:55 +0100

Andy,

I think your use-case of embedded clients actually validates my
proposal of masking-as-extension.

You're not concerned about intermediary abuse, so you can write a
simple client that does not use any masking extension and just send
the packets in the clear. However, I expect the browsers, with run
arbitrary 3rd party code, will be a little more circumspect and
obviously do worry about the small number of silly intermediaries out
there, thus they would insist on some kind of masking extension.

But having masking as an extension allows both types of clients to be
happy. Using gzip(+salt?) as the default masking extension means that
we get some savings in return for the expense of masking.

Isn't this exactly why we put extensions into the framing?

cheers

On 20 December 2010 11:17, Andy Green <[email-masked]> wrote:
> On 12/20/10 09:48, Somebody in the thread at some point said:
>>
>> On 20 December 2010 00:42, Bjoern Hoehrmann<[email-masked]>  wrote:
>
> Hi -
> Websockets is interesting from my side because it will enable simple, fast
> UI handoff for embedded devices.  I have written a C library libwebsockets
> for that purpose http://git.warmcat.com/cgi-bin/cgit/libwebsockets/; it
> takes care about pre-and-post buffer allocation for example to allow
> zerocopy flow for the bulk data through it when the protocol headers and
> trailers are added.
>
> Requiring gzip or TLS / SSL or xor hashing or AES on the payload data does
> not fit that kind of use-case, and frankly it seems driven either by "throw
> encryption at it" or fatigue with trying to get general agreement for what
> seems to me a very decent current situation with the -03 draft or Ian's
> draft that added HELLO: -76 is working great in the real world already and
> these are small changes on top of that.
>
>
> That is not cool.  Cool is I can get a weak ARM7 or ARM9 device to have a
> crossplatform 2011 class UI with just a network connection even though it's
> visualizing a lot of data.  I can do that with -76, -03 or the -03 + HELLO.
>
> Insecure intermediaries are not a websocket problem; whatever attack makes
> trouble for them can be performed without websockets if something else is
> willing to send suitable packets on both sides of it.
>
> With Firefox turning off websockets by default, we now seem to be on a path
> to websockets dying before it gets widely used, or hobbled by requiring
> payload munging so it is no longer lightweight.
>
> I saw Ian Fette wrote before that making it impossible for ws packets to
> look like valid HTTP should be enough... it really should be enough.
>
> -Andy
>

---

From: "Alexander Philippou" <[email-masked]>
Date: Mon, 20 Dec 2010 15:34:34 +0200

> To address to issue of efficiency of masking, why not use a gzip as the masking mechanism, since this has been an oft requested feature anyway.  I understand that with pure gzip, it is probably possible to invent binary content that will result in known compressed content, but I'm sure that if we mixed some random salt into the dictionary (and maybe each frame?), we'd get enough unpredictability (and the hello frames can exchange the salt).  This way the masking will give us benefits as well as obfuscating the content.
> 
> Furthermore, I'd propose that we make the gzip element a WS extension (in terms of the current framing) and gzip would just be the default. That way, consenting clients/servers would be free to replace gzip with other compressing mechanisms, with real encryption or even with no masking (if the threat of silly intermediaries is known not exist).

+1

I would go along with both the gzip masking mechanism and the gzip extension. It takes into account the needs of non-browser clients too.
 
Alexander

---

From: Dave Cridland <[email-masked]>
Date: Mon, 20 Dec 2010 13:42:16 +0000

On Mon Dec 20 09:48:01 2010, Greg Wilkins wrote:
> anyway.

300k per session at each end - to my mind, that's a compelling reason  
why not.

Of course, reducing the compression levels will reduce the memory  
load drastically, but it'll also decrease the masking benefits of  
gzip.

Finally, although one could sneakily place "GET", "HTTP/1.1\r\n", etc  
into a preloaded dictionary, simply sending a frame with more than  
the window size of data will defeat that, I think.

Nice idea, though.

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: Greg Wilkins <[email-masked]>
Date: Mon, 20 Dec 2010 14:49:28 +0100

On 20 December 2010 14:42, Dave Cridland <[email-masked]> wrote:
> 300k per session at each end - to my mind, that's a compelling reason why
> not.

I'm not sure it is really 300k?, but even if it were, then making the
masking an extension means that it is easy to come up with
aggregators/balancers that offload that burden from the app servers
and could be more efficient with their buffer usage.

> Of course, reducing the compression levels will reduce the memory load
> drastically, but it'll also decrease the masking benefits of gzip.
>
> Finally, although one could sneakily place "GET", "HTTP/1.1\r\n", etc into a
> preloaded dictionary, simply sending a frame with more than the window size
> of data will defeat that, I think.
>
> Nice idea, though.

I'm prepared to say that gzip might not be THE masking algorithm we
make as default.   The key thought is to make masking an extension, so
it can be switched off when not needed.  The secondary thought, is why
not make the masking do something useful like compression.   Even if
we have to tweak gzip, surely that is better than inventing our own
masking protocol?

cheers

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Dec 2010 07:11:35 -0800

On Mon, Dec 20, 2010 at 5:49 AM, Greg Wilkins <[email-masked]> wrote:

> > On Mon Dec 20 09:48:01 2010, Greg Wilkins wrote:ce idea, though.
>
Quite the contrary. The idea here is to have something easily understood
with clear security properties, not to pile complication on top of
complication
in hopes it will be secure.

-Ekr

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 20 Dec 2010 17:42:27 +0100

> in hopes it will be secure.

Eric,

what was that you said about ideas being rejected out of hand?

There is no "hoping" about security with this idea, nor any additional
layers of complication other than what has already been implemented in
the framing.

I don't really see the complication?  We already have an extension
mechanism and gzip (or similar) is almost certain to be available as
an extension.
We should be able to quickly determine if it has suitable security
properties (ie attacker cannot form payload that will look like HTTP
when gzipped), in which case gzip is a candidate masking.
If we cannot show that  gzip is a secure enough masking mechanism,
then we simply create an extension based on one of the proposed
masking mechanism (XOR or  AES etc.).   The key thing is to make the
masking an extension using the already defined extension mechanism.
Browsers can insist on using strong masking, but within a data centre,
the extension may be dropped so that the efficiency concerns can be
better met.

A few months ago, we were all arguing about what was the best way to
achieve compression - frame by frame, or stream based.   Now there is
a concern about the efficiency (or otherwise) of applying some kind of
weak cypher to the payload to avoid sending data in the clear.
Surely there is some commonality we can find to combine these two use
cases.  We certainly don't want to mask all the payloads with some
rolling cypher and then try to compress, as the cypher will probably
destroy most of the ability to well compress the data.

regards

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Dec 2010 11:59:18 -0800

> what was that you said about ideas being rejected out of hand?
What I said was that I didn't want to spend a lot of time writing something
up
which the WG already had decided I didn't want. I don't see that that
somehow
prevents me from making a rapid judgement on ideas which I don't think are
good.

> when gzipped), in which case gzip is a candidate masking.

Really? How, exactly, do you propose to do that?

It's perfectly clear that gzip allows the attacker quite a bit of control
over
the output, and for efficiency it must be possible for gzip to generate
practically any candidate output (otherwise you're giving away
efficiency) so now you're going to need to make some heuristic argument
about the level of that control (much like you have been making heuristic
arguments about the framing). I'd rather simply have a design that doesn't
require complicated analysis, especially not an analysis that will need to
be repeated if we ever want to go to another compression algorithm.

> the extension may be dropped so that the efficiency concerns can be
Sure sounds complicated to me.

> destroy most of the ability to well compress the data.

Yes, you compress first.

FWIW, I'm not very impressed by this argument about the performance of
masking.
As has been noted at least once, masking is only necessary on the client
side,
and I'm not overly concerned about the modest amount of overhead offered
by doing masking on the client side from a JavaScript application,
especially in
view of the fact that WebSockets doesn't even specify an API in which the
string is not directly provided by the JS code.

-Ekr

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 20 Dec 2010 22:08:39 +0100

> FWIW, I'm not very impressed by this argument about the performance of

Well it does appear to be an impediment for some... so I'm just trying
to look for ways to overcome those objections by making masking
optional in some environments and/or make the masking algorithm do
something useful as well.

> Sure sounds complicated to me.

Where is the additional complexity?   We already have an extension
mechanism, so it is just defining that the browsers will have a
default extension that will apply masking.

> efficiency) so now you're going to need to make some heuristic argument

You mean like the  argument that you've been making about CONNECT being safe?

No I was not proposing that.  I was proposing that we analyse the
algorithm and byte stream standard. but as you appear to have
dismissed this out of hand, I guess there is not much point doing that
work.

So do you have any bright ideas how to mitigate the objections to
masking and make some actual progress??

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Dec 2010 13:36:52 -0800

> something useful as well.

Yes, I appreciate that but it's unclear that it meets the security goals,
whereas
masking (at least the AES-CTR version in our paper) does.

> default extension that will apply masking.
What's complicated is the analysis that needs to be required to convince
oneself that it's actually secure.

> You mean like the  argument that you've been making about CONNECT being

You know what would be really great? If you didn't put words in my mouth.

As far as I know I haven't ever said that CONNECT was safe. Rather, I said
that the alternatives were demonstrably unsafe and CONNECT was the best
I knew how to do. If you can find I message where I said CONNECT was safe
I will retract said message. If not, I believe your apology is in order.

> dismissed this out of hand, I guess there is not much point doing that

Yes, I think that's a waste of time, not because I've rejected it out of
hand
but because I understand how compression algorithms work and believe
that the analysis will not yield a convincing result. If you care to do the
detailed work and offer such demonstration, I'll be happy to review it
Otherwise, I don't see that it's incumbent on my to burn time seriously
exploring an avenue that I think is fruitless. (Which, as I noted above,
is my position with regard to NPN as well.)

On a more procedural note, this message and the previous one have the
tone that you've somehow caught me in a contradiction between not
wanting to work on NPN if people aren't going to accept it and not wanting
to seriously consider your gzip alternative. I don't find that sort of
gotcha game particularly interesting. Even if it were, I don't think you
understand
my position on NPN correctly. I don't think it's in any way inappropriate
for
people to say they don't want a TLS-only solution and so they're dismissing
NPN out of hand. It's not an engineering judgement I happen to share, but
it's a legitimate one. I simply don't want to invest a lot of energy
producing
something that doesn't meet what people want.

> masking and make some actual progress??

I'd like to see some concrete non-FUD arguments against masking on the
client side.

-Ekr

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 20 Dec 2010 23:49:01 +0100

> You know what would be really great? If you didn't put words in my mouth.
[...]
> tone that you've somehow caught me in a contradiction... I don't find that sort of
> gotcha game particularly interesting.

I was not trying to play gotcha and apologize if my emails were taken
as somewhat combative in tone.
However, I found your summary judgement to be rather dismissive and
was trying  to use your own words to solicit a bit more consideration
and flexibility in your position.

> I will retract said message. If not, I believe your apology is in order.

Do you see the safety of your proposal coming from CONNECT or from masking?

Do you think that   GET+Upgrade with masking(AES-CTR) would be
sufficiently secure?

What about GET+Upgrade+Hello+robust framing+ AES-CTR masking?

> whereas masking (at least the AES-CTR version in our paper) does.

OK, so let's put AES-CTR into an extension and may also allow some
flexibility for those concerned about efficiency.

> oneself that it's actually secure.

You are mixing up the two aspects that I have suggested.

One  is to put the masking into an extension, thus making it able to
be turned off or replaced in some environments.
The other suggestion was to consider gzip as the masking algorithm.
If it is too much to consider gzip as a masking algorithm, could you
at least consider making AES-CTR masking an extension

regards

---

From: Maciej Stachowiak <[email-masked]>
Date: Mon, 20 Dec 2010 14:50:53 -0800

> we have to tweak gzip, surely that is better than inventing our own

Others have commented on the suitability of gzip as a masking algorithm.

I'm, curious why it is important to make client payload masking an extension that can be turned off. You said it can be switched off when "not needed". However, payload masking is intended to provide some protection for the origin server, explicit server-side intermediaries (such as virtual hosting dispatchers), and intercepting proxies that neither the client nor the server knows about. So I see two flaws with the premise that sometimes masking is known to be not needed:

1) You can never know with certainty whether an intercepting intermediary is in use.
2) In the case of attacks against intercept proxies and virtual hosting setups, the server is under control of the attacker, so it's dangerous to let it decide masking is not needed.
3) Part of the purpose of masking is to protect buggy WebSocket origin servers from attack by HTTP. It seems to me that the ones that are buggy are the ones most likely to be overconfident about their security.
4) It's not safe to let JavaScript code in the browser decide that masking is not needed, because it could be hostile (by assumptions of the Web attacker threat model).
5) Because of factors 1-4, the client protocol implementation has no way of determining masking is not needed either.

For these reasons, it seems imprudent to make client-side payload masking optional. If we accept that it provides security benefits, it should be mandatory. Given this, it does not seem helpful to entangle it with a mechanism for negotiating optional protocol extensions.

Regards,
Maciej

---

From: Maciej Stachowiak <[email-masked]>
Date: Mon, 20 Dec 2010 14:54:16 -0800

> flexibility for those concerned about efficiency.

For reasons mentioned in a separate email, making masking optional is unsound. The server and Web content can't be trusted to decide, and the client protocol implementation doesn't have the information to decide. Can you describe a scenario where it would be reasonable to turn masking off, and which of the parties to the interaction can decide that?

In any case, if you think about AES-CTR masking as being client-only, it's hard to see how there is even a strong efficiency argument against it. It won't interfere with the server's ability to do sendfile(), and client-to-server traffic is unlikely to be of such volume that decryption is a bottleneck.

Regards,
Maciej

---

From: Greg Wilkins <[email-masked]>
Date: Mon, 20 Dec 2010 23:59:37 +0100

Maciej,

I have said several times that masking should NOT be optional from the
browser for exactly the reasons that you list.  I think a browser
should not accept any handshake response that did not agree to use the
masking extension.
But making it an extension would allow the extension to be terminated
at the boundary of a data centre so that masking would not need to be
used when WS connections are in a well known safe environment.

regards

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Dec 2010 15:15:16 -0800

> and flexibility in your position.

I believe I am being appropriately flexible with respect to this gzip
proposal.

> Do you see the safety of your proposal coming from CONNECT or from masking?

Well, once again, I didn't say that CONNECT was safe. I said that the
alternatives
were demonstrably unsafe.

> sufficiently secure?

Well, as has been observed repeatedly, "sufficiently" is a difficult
concept. With that
said, I think that the AES-CTR solution with a random per-write nonce is
secure
regardless of the handshake. However, two notes about this:

(1) I don't believe that that's true if we do any of the non-AES masking
mechanisms.
(2) As Adam observes, there is an argument that the handshake should
guarantee
the path to some extent.

> flexibility for those concerned about efficiency.
Like Maciej, I think this whole extension concept for a fundamental security
feature is wrong. It's simply not that difficult to remove the masking.

> The other suggestion was to consider gzip as the masking algorithm.

Yes. This is what I believe is too complicated to analyze.

> at least consider making AES-CTR masking an extension
I believe this is a bad idea.

-Ekr

---

From: Maciej Stachowiak <[email-masked]>
Date: Mon, 20 Dec 2010 15:16:42 -0800

> used when WS connections are in a well known safe environment.

Let me check first if I understand the scenario. You have the true client B, a data center WebSocket terminator T, and a further true internal server S. T acts as a server to B, and as a client to S. T and S presumably negotiate somehow to turn off masking. 

Assuming my understanding is correct, I have a few questions and comments:

1) Why does this need to be done at all? Is there any particular reason that keeping payload traffic masked between the terminator and the internal server is a problem? Is there anyone who would be totally happy with masking from client to data center terminator, but considers maintaining the masking within their data center a showstopper?

2) Even if it is needed, why does this use case need to be addressed in the protocol spec? It seems to me that no-masking mode is not safe for use on the public Internet. So it doesn't need to be part of an Internet protocol. It could be a private convention.

3) If it is needed and it does need to be part of the protocol spec, shouldn't it be defined the other way around, where no-masking is an extension? No-masking mode is only usable in exceptional circumstances, by your description.

4) I note further that it's dangerous for origin servers to be written in a way where they will accept a connection that disables masking. Part of the purpose of masking is to protect overly lenient origin servers from attacks using an HTTP client. If the client could force masking off, then it might be possible to force no-masking mode on in a browser-to-server interaction rather than a data-center-internal interaction. Thus, it's dangerous to make no-masking mode something negotiated at runtime, instead of explicitly configured.

Regards,
Maciej

---

From: Brian <[email-masked]>
Date: Mon, 20 Dec 2010 15:33:43 -0800

I like this idea!  It seems to address the concerns appropriately, and
the extra round-trip only applies for when you need the extra speed of
sending unmasked data.

Most usages of the protocol may never need the "upgrade" at all.

7-bit might be a bit of a misnomer, unless you're thinking of
Base64-encoding everything, since all you'd really need to do is
escape the CRs and LFs

Brian

On Sun, Dec 19, 2010 at 9:05 PM, Willy Tarreau <[email-masked]> wrote:
> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi
>

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 00:44:54 +0100

> Let me check first if I understand the scenario. You have the true client B, a data center WebSocket terminator T, and a further true internal server S. T acts as a server to B, and as a client to…

I think "negotiate" is probably two strong a word.  I think we have
always been more about extension declaration rather than any
haggling... but other than that yes that is what I'm saying.

> 1) Why does this need to be done at all? Is there any particular reason that keeping payload traffic masked between the terminator and the internal server is a problem? Is there anyone who would be…

The view has been expressed by many that masking is expensive and can
prevent using mechanisms like sendFile.   It is already typical to
offload TLS  within data centres, so I see no reason why it would not
also be desirable to offload something like AES. HTTP well supports
such offload.

> 2) Even if it is needed, why does this use case need to be addressed in the protocol spec? It seems to me that no-masking mode is not safe for use on the public Internet. So it doesn't need to be p…

Because data centre are made up of equipment from many vendors and the
interoperability of true internet standards is vitally important to
make data centre work.    We can't say that standards end at the data
centre boundary. HTTP standardizes much of the communication within
the data centre as well as on the internet.

> 3) If it is needed and it does need to be part of the protocol spec, shouldn't it be defined the other way around, where no-masking is an extension? No-masking mode is only usable in exceptional ci…

That's just semantics.   But yes, we could make it so that if the
handshake said nothing, then the masking  would be applied using the
framing extension mechanism.  So yes, we could negotiate to turn it
off and have it on by default.  The key thing would be to use the
existing extension mechanism of framing to carry any key, so that if
it was turned off, then there would be no cost.

> 4) I note further that it's dangerous for origin servers to be written in a way where they will accept a connection that disables masking. Part of the purpose of masking is to protect overly lenien…

I don't think this is a realistic situation as I'm not proposing that
anything can turn off masking in the browser.   Masking would be non
optional for browsers.

regards

---

From: Jamie Lokier <[email-masked]>
Date: Mon, 20 Dec 2010 23:45:42 +0000

Alexander Philippou wrote:
> > Furthermore, I'd propose that we make the gzip element a WS
> > extension (in terms of the current framing) and gzip would just be
> > the default. That way, consenting clients/servers would be free to
> > replace gzip with other compressing mechanisms, with real
> > encryption or even with no masking (if the threat of silly
> > intermediaries is known not exist).
> 
> +1
> 

Except small-memory clients.  It's not very friendly to those.

-- Jamie

---

From: Gabriel Montenegro <[email-masked]>
Date: Mon, 20 Dec 2010 23:47:29 +0000

I tend to agree that if we're adding masking into the protocol, it's simpler and safer if it is always on. It does seem like it is only necessary when operating in the clear ("ws" URIs), as when operating with HTTPS ("wss" URIs) SSL already provides better masking/encryption. If so (please correct me if I'm wrong), it could be hardcoded required masking with "ws" but not with "wss".

Eric, you mention that you'd consider AES-CTR mode  to be safe to deliver the required security guarantees in this case. If this is so, then the question of crypto agility comes into play. Not sure if we'd need to solve it now, as long as it is clear how it will be solved eventually (e.g., by using appropriate headers to indicate anything other than AES-128-CTR for the masking.

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On Behalf Of
> Maciej Stachowiak
> Sent: 20 December, 2010 15:17
> To: Greg Wilkins
> Cc: Server-Initiated HTTP; Bjoern Hoehrmann
> Subject: Re: [hybi] Handshake security proof
> 
> 
> Let me check first if I understand the scenario. You have the true client B, a
> data center WebSocket terminator T, and a further true internal server S. T
> acts as a server to B, and as a client to S. T and S presumably negotiate
> somehow to turn off masking.
> 
> 1) Why does this need to be done at all? Is there any particular reason that
> keeping payload traffic masked between the terminator and the internal
> server is a problem? Is there anyone who would be totally happy with masking
> from client to data center terminator, but considers maintaining the masking
> within their data center a showstopper?
> 
> 2) Even if it is needed, why does this use case need to be addressed in the
> protocol spec? It seems to me that no-masking mode is not safe for use on the
> public Internet. So it doesn't need to be part of an Internet protocol. It could
> be a private convention.
> 
> 3) If it is needed and it does need to be part of the protocol spec, shouldn't it
> be defined the other way around, where no-masking is an extension? No-
> masking mode is only usable in exceptional circumstances, by your
> description.
> 
> 4) I note further that it's dangerous for origin servers to be written in a way
> where they will accept a connection that disables masking. Part of the
> purpose of masking is to protect overly lenient origin servers from attacks
> using an HTTP client. If the client could force masking off, then it might be
> possible to force no-masking mode on in a browser-to-server interaction
> rather than a data-center-internal interaction. Thus, it's dangerous to make
> no-masking mode something negotiated at runtime, instead of explicitly
> configured.
> 
> Regards,
> Maciej
>

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Dec 2010 15:47:57 -0800

On Mon, Dec 20, 2010 at 3:44 PM, Greg Wilkins <[email-masked]> wrote:

> > Let me check first if I understand the scenario. You have the true client
> B, a data center WebSocket terminator T, and a further true internal server
> S. T acts as a server to B, and as a client to S. T and S presumably
> negotiate somehow to turn off masking.
>
> > 1) Why does this need to be done at all? Is there any particular reason
> that keeping payload traffic masked between the terminator and the internal
> prevent using mechanisms like sendFile.

But as Maciej and I have both observed, this argument does not apply to
traffic
from the client to the server, which is the problematic case.

-Ekr

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Dec 2010 15:54:47 -0800

On Mon, Dec 20, 2010 at 3:47 PM, Gabriel Montenegro <[email-masked]>wrote:

> I tend to agree that if we're adding masking into the protocol, it's
> simpler and safer if it is always on. It does seem like it is only necessary
> when operating in the clear ("ws" URIs), as when operating with HTTPS ("wss"
> URIs) SSL already provides better masking/encryption. If so (please correct
> me if I'm wrong), it could be hardcoded required masking with "ws" but not
> with "wss".
>

Actually, this isn't quite correct: there is no requirement in the CTR-based
AES
modes of TLS that the nonce for the next packet be concealed from the
TLS-using
application, in which case the masking is predictable.

Eric, you mention that you'd consider AES-CTR mode  to be safe to deliver
> the required security guarantees in this case. If this is so, then the
> question of crypto agility comes into play. Not sure if we'd need to solve
> it now, as long as it is clear how it will be solved eventually (e.g., by
> using appropriate headers to indicate anything other than AES-128-CTR for
> the masking.

I'm not sure we really need agility here, but if we do I think we could just
have
agility for the core algorithm and specify CTR

-Ekr

> B, a
> that

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Mon, 20 Dec 2010 15:55:44 -0800

Isn't this what Willy already proposed in
http://www.ietf.org/mail-archive/web/hybi/current/msg04851.html ?

I feel like we already had that discussion, but maybe I'm mis-interpreting
something.

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Dec 2010 16:16:37 -0800

Regardless, I don't really understand how this is supposed to work. Is the
intention
that CRLFs are *never* sent in which case you need to scrub all the data and
masking
starts to look more efficient. Or is the intention that you somehow verify
the path
is clean and then you allow CRLFs, in which case this recduces to the
problem
of designing a handshake.

-Ekr

2010/12/20 Ian Fette (イアンフェッティ) <[email-masked]>

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 01:32:48 +0100

> Except small-memory clients.  It's not very friendly to those.

Indeed - not all clients are browsers, and thus not all clients are
susceptible to attacks from running 3rd party javascript.
Thus it would be good if any masking was done as an extension that
could be turned off if it is not needed.

cheers

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Dec 2010 16:36:57 -0800

On Mon, Dec 20, 2010 at 4:32 PM, Greg Wilkins <[email-masked]> wrote:

> >> I would go along with both the gzip masking mechanism and the gzip
> extension. It takes into account the needs of non-browser clients too.
> >
Again, why?

Doing the masking is incredibly trivial by comparison to (for instance) the
handshake state
machine. I just don't see the benefit of complicating the protocol for this.
What resource
are you conserving?

-Ekr

---

From: John Tamplin <[email-masked]>
Date: Mon, 20 Dec 2010 19:48:38 -0500

On Mon, Dec 20, 2010 at 7:16 PM, Eric Rescorla <[email-masked]> wrote:

> that CRLFs are *never* sent in which case you need to scrub all the data
> and masking

Right -- the attack that has been discussed is against transparent proxies,
which by their nature you can't tell if they are there or not.  So, even if
you successfully complete a WebSocket handshake, you don't know for sure if
there is a proxy along the way that can't be confused by allowing the
attacker free reign to send whatever content they like.

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

---

From: Bjoern Hoehrmann <[email-masked]>
Date: Tue, 21 Dec 2010 03:30:48 +0100

>the masking mechanism, since this has been an oft requested feature

It's not clear to me that this is something that needs adressing. As I
note in the writeup linked above, client->server communication usually
does not involve a lot of data that an attacker has meaningful control
over (keeping in mind that for, say, file upload, you can use HTTP with
no masking and don't need Websocket) so processing cost is dominated by
other factors. And a couple of bytes of key data per frame does not in-
crease transfer cost by much for most applications (had we all migrated
to IPv6 already I'd not even mention the transfer cost).

>no masking (if the threat of silly intermediaries is known not exist).

In my writeup I assume that the masking method would offer optionality
by means of a suitable key. For instance, if the masking method is just
XOR, you could use zero as key and send the data verbatim. I've also
noted the drawback there.
-- 
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: Tue, 21 Dec 2010 06:56:52 +0100

> something useful as well.

That was also th reason why I suggested that we use masking at the
beginning (eg: hello frames) and can remove it after the first
exchange proved to work.

Willy

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Dec 2010 22:05:03 -0800

> beginning (eg: hello frames) and can remove it after the first

As I said earlier, this reduces to providing a handshake which we can
demonstrate
is secure, which is precisely the problem that appears to be difficult.

-Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 07:12:21 +0100

> Base64-encoding everything, since all you'd really need to do is

indeed, in some environments, base64 might be easier to use than a
complex bit-based encoding. And it would not waste much more bandwidth.

Willy

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 07:17:55 +0100

> attacker free reign to send whatever content they like.

The principle is to prevent both sides from sending binary data (including
CRLF) until they have a proof that a tunnel is really established. That
means that the CRLFs may only be sent through a validated chain. If a bad
transparent or intercepting proxy in the middle decides to interprete any
part as plain HTTP, it will not find any CRLF to get a request and will
not forward the data in at least one direction (at least the data supposed
to be a new request will either cause an abort or be blocked).

Also it has the advantage that during this phase, the client can easily
detect that something went wrong in the middle, because if an intermediary
returns an HTTP error, it will not match the allowed character set.

Willy

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 07:18:43 +0100

> I feel like we already had that discussion, but maybe I'm mis-interpreting

Yes, except that at this time I hadn't thought about disabling the masking
once the channel is validated.

Willy

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 09:05:04 +0100

On 21 December 2010 07:05, Eric Rescorla <[email-masked]> wrote:
> demonstrate is secure, which is precisely the problem that appears to be difficult.

Eric,

if there is a handshake that we can demonstrate is secure, then we
don't need masking.

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 00:11:50 -0800

> if there is a handshake that we can demonstrate is secure, then we

Yes, I agree with that, but since I'm unaware of any such handshake
(including
the one described in our paper) and none of the suggestions I've seen for
how
to construct such a handshake and then demonstrate it's secure are very
convincing, I'm not very sanguine about that.

-Ekr

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 09:43:22 +0100

> convincing, I'm not very sanguine about that.

Then I think the inverse is true.  If we have demonstrably secure
masking, then it is not necessary to have a demonstrably secure
handshake. So I think it would be very beneficial to have a proposal
written up that is just about masking and excludes consideration of
using Upgrade vs CONNECT, Hello frames,  bogus hosts or anything else
that is designed to make the handshake more robust.   We could even
apply masking to the -76 handshake and that would represent a
significant gain.

Of course having a robust (and sane) handshake is still good, but I
think those ideas need to be considered separately from masking.

regards

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 10:00:38 +0100

On Tue, Dec 21, 2010 at 09:43:22AM +0100, Greg Wilkins wrote:
> If we have demonstrably secure

OK, here's what I'm proposing. We should support two encoding types :
  - raw frames
  - base64-encoded frames

The base64 frames have the advantage of not containing any CR, LF, colons
or spaces, so that even the laziest proxy we could think of (such as the
ones suggested by Bjoern) has no chance of finding there a method, a URL
or even a header.

We would move the MORE/FIN bit of the framing to one of the RSV bits so
that we replace it with a RAW/encoded bit. That way, we can have a per-frame
encoding, with raw frames always starting with bit7 == 1, and encoded frames
always starting with bit7 == 0. Having a per-frame encoding makes decoding
easier (no state to maintain) and will also help with multiplexing later.

A WS agent MUST always use base64-encoded frames unless it knows that the
other side has already received one of its frames, which indicates that
the tunnel is really set up.

That would mean using encoded frames for initial exchanges, and probably
most small frames, and switching to raw frames for sending binary contents
or data that needs to benefit from any possible offloading (eg: sendfile).

That does not remove the usefulness of the initial hello frames, which are
still needed to ensure the channel works and to try to get incompatible
proxies to fail ASAP.

All that could then still be used over the current GET+101 handshake which
has the big advantage of being standards-compliant.

Any opinion on this ?

Regards,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 01:09:10 -0800

> the tunnel is really set up.

I don't agree that this demonstrates that no transparent proxy has been
fooled.

-Ekr

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 10:18:02 +0100

> I don't agree that this demonstrates that no transparent proxy has been

I agree.   Unfortunately the receipt of packets correctly does not
indicate that we have not fooled a transparent proxy, because the
proxy is after all transparent.

The problem that we are trying to avoid with masking, is not to
successfully create a tunnel, but to prevent an intermediary
incorrectly caching data from the stream which it will use when
servicing other requests, potentially from other clients.

I think that if we are in an environment where masking is deemed
necessary, then I think it will have to remain on for the duration of
the connection, because I can't imagine a test that will prove that a
transparent intermediary has not been fooled.  As browsers will mostly
run in such environments, I think it is reasonable to have masking
always on for browsers.    But I also believe that simple clients and
controlled environments should be able to establish WS connections
without masking without the need to go outside of the standard.

regards

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 10:53:05 +0100

> servicing other requests, potentially from other clients.

But an HTTP stream is before all a succession of messages (requests/responses).
A proxy does not randomly pick some data within a stream, perpetually remaining
out of sync with the stream and from time to time getting in sync just to annoy
us.

Of course we could try to invent such a component deliberately to try to make
any of our handshakes fail, but :

  1) it would be hard to implement
  2) it would not correctly work with HTTP

> transparent intermediary has not been fooled.

Greg, I don't follow you. In your previous proposals, you considered that
having a high bit set in the first byte of a frame was enough to ensure
that an intermediary would reject it. Now having a long stream of chars
terminated by a byte with the high bit set is not enough anymore.

> As browsers will mostly
> always on for browsers.

I would generally agree with that except that if some want to use it to
upload video, it could increase their bandwidth usage if the masking
increases the payload size.

> But I also believe that simple clients and

Regards,
Willy

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 11:19:51 +0100

> out of sync with the stream and from time to time getting in sync just to annoy

Well I also think such intermediaries do not exist, or if they do,
then there will be vanishing few of them. But in the spirit of
compromise, I recognise that others are very worried by the
possibility of such intermediaries  - so much so that we appear to
have been paralysed by the fear and apparently we can't even flip a
single bit in the framing until we have found a 100% solution that
defeats these rumoured monster intermediaries (and I'm not belittling
the concerns expressed by others  - I'm just expressing frustration
that these concerns have caused a halt all progress).

> terminated by a byte with the high bit set is not enough anymore.

Indeed,  I think that Hello frames and a high bit on every frame
should be sufficient to throw off intermediaries that are parsing HTTP
streams.
But I cannot prove that to be the case.

So given that it can't proven that such intermediaries don't exist and
it can't prove that robust defences are 100%, then we have to assume
that such intermediaries do exist and that no amount of preprended
illegal HTTP will prevent subsequent HTTP payloads from being wrongly
parsed.   So all our squabbling over handshakes is for naught and the
only solutions are masking  or full encryption. Thus in the spirit of
making progress, I'm now advocating masking. However, I would like to
see the masking implemented in such a way (eg as an extension) so that
it does not need to be used in environments where it is clear that it
is not necessary.

So while I tend to agree with you that an intermediary that passes a
few masked WS frames is highly unlikely to be one that will suffer
from cache poisoning, again I don't think we can prove that.   As
these concerns are mostly coming from the browser community, I'm thus
advocating that browsers always have masking turned on - hoping that
this will get us past this road block and avoid the call for bogus
hosts and possibly avoid the debate about the misuse of CONNECT.

> increases the payload size.

true.   No such thing as a free lunch!

If nobody is prepared to accept some compromises in their stated
positions and beliefs, then we may as well give up now. I think
optional masking client->server (with it being mandatory for browser
clients), is a small price to pay give surety of defence against poor
intermediaries and to progress this WG.

cheers

---

From: Bjoern Hoehrmann <[email-masked]>
Date: Tue, 21 Dec 2010 11:37:11 +0100

>apply masking to the -76 handshake and that would represent a

If the attacker cannot control the bytes on the wire in a meaningful way
then the handshake does not need to establish that no harm can come from
the attacker being able to control the bytes on the wire, right, but the
handshake is still necessary in that only Websocket endpoints should be
able to establish a Websocket connection between them.

If a straw man helps, how about this: each frame is preceded by an un-
predictable key and all subsequent data for that frame is encoded using

  out[pos] = in[pos] ^ key[pos % keylength]

For an attacker to control the bytes in `out` he needs to know the key
before asking the browser to send some data, or he needs to get lucky
in that the browser chooses a compatible key. The odds of the attacker
getting lucky depend on the keylength, and the attacker cannot predict
the key in advance since we required that it is unpredictable.

This obviously requires that the attacker cannot modify the data that he
already asked the browser to send, but so long as that is the case the
attacker cannot control the bytes on the wire within the odds permitted
by the keylength since he cannot predict an unpredictable value that
he'd need to apply to the data before asking the browser to send it so
it puts the desired bytes on the wire.

In http://lists.w3.org/Archives/Public/www-archive/2010Dec/0009.html I
noted some of the problems and benefits of such an approach. We also had
some issues not mentioned there on the list, for instance, you'd need a
custom dissector to read the text in text frames in Wireshark.
-- 
Björn Höhrmann · mailto:[email-masked] · http://bjoern.hoehrmann.de
Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 11:59:33 +0100

On 21 December 2010 11:37, Bjoern Hoehrmann <[email-masked]> wrote:
> but the

True.  And that is why I've been advocating improvements to the
handshake that are entirely unrelated to the issue of cache poisoning
intermediaries.

>  out[pos] = in[pos] ^ key[pos % keylength]

Note that we already have an extension mechanism in our framing, so
there is no need to prepend the key to the payload.  It should be put
into the extension data of our framing.

But other than that, I've no objection to such a masking algorithm and
it is good that it should not suffer from crypto export restrictions
etc.

> custom dissector to read the text in text frames in Wireshark.

The good thing about a masking algorithm that carries the key in the
extension data, is that every frame remains self describing and
writing such plugins for wireshark will be pretty simple.
Masking algorithms that rely on rolling keys will be harder to work
with wireshark as you will need to capture the entire stream in order
to decode any given frame.

cheers

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 12:18:23 +0100

> But I cannot prove that to be the case.

But here we're not only talking about having an intermediary fail on
that, but we're saying that the intermediary reliably transfers data
in both directions while this does not look like HTTP traffic at all,
but at the same time it would consider some subsequent traffic after
it as HTTP. That's the point that does not make sense at all to me.

Granted we don't know if a totally stupid intermediary considers a
4K uninterrupted stream as an HTTP method. But if this stream reaches
the other side and a response comes, it could not be an HTTP method,
because an intermediary needs to synchronize on something. I'd even
claim that if someone managed to build such a complex monster to
deliberately be fooled with our handshakes, it would also be fooled
by plain HTTP.

> parsed.

It's not only "prepended", it "forwarded".

If we're imagining such possibilities, we could as well imagine some
intermediaries that automatically try to decipher anything that does
not look like HTTP and will systematically get over all of our payload
masking methods.

We should fix a limit at some point. The reason for this WG to be
paralyzed is that we're constantly reinventing new monsters just to
be happy to frighten ourselves. We're not in a block buster movie and
reality need to have a bit more of consideration in my opinion.

> from cache poisoning, again I don't think we can prove that.

Greg, you're falling in a trap that security people often like to open,
which consists in asking someone to prove the impossible in order to
conclude that their solution does not cover all cases. That's just as
if you were asked to prove there are no aliens on earth. Better wait
for someone to prove there are.

I really like Bjoern's approach which consists in thinking what a lazy
implementation could look like. It tends to give insights about what we
should fear. That was what Ian Hickson was interested in at the beginning
too : what if some parsers only rely on strstr() etc...

And something which does not minimally comply with standards and is does
not even match a lazy implementation pattern starts to smell like something
that was deliberately implementated to try to prove us wrong. We don't have
to care about those cases, they prevent us from making any progress.

Thanks,
Willy

---

From: Bjoern Hoehrmann <[email-masked]>
Date: Tue, 21 Dec 2010 12:22:14 +0100

>into the extension data of our framing.

You have to put it in some fixed position if you want to encode the meta
data, and the position of the extension data, as I understand it, is not
fixed. The goal of the straw man was to show how the attacker is
prevented from controlling any of the bytes, so it encoded the metadata.
Applying the key only to the application data may also be an option, but
that would mean the attacker can control some of the bytes.
-- 
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: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 08:09:17 -0800

> that these concerns have caused a halt all progress).

In fact, you actually are belittling those concerns. However, since your
opinion seems to be based almost exclusively on handwaving and argument
from incredulity, for some reason I'm having trouble being moved by it.

I don't really have the time or energy to write a detailed response to this
little
screed, but suffice to say that I don't share your opinion of what has
happened
in the past few months.

-Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 19:22:27 +0100

> from incredulity, for some reason I'm having trouble being moved by it.

Eric, I don't think it's necessary to adopt that tone. In my opinion,
the handwaving is what consists in agitating strawmen about hypothetical
implementation bugs that for quite strange reasons only TLS could work
around.

Your (and Adam's) work has been incredibly useful to prove that there are
some buggy implementations and to classify them in several types.

However, it does not show any evidence of those magical components that act as
desired depending on the intent of the author of a request (or response) and
which would be smart enough to decide what part of the stream is WS data and
what part is an attack they must decide to be fooled with. Once again, I'm
sure someone could deliberately write one such thing to prove me wrong but
that's not the point.

We all know you'd like to see TLS adopted by WS and I can understand it,
considering your involvement around it. There's nothing wrong with this,
it has advantages and inconvenients. But putting a bit more of intellectual
honnesty in the debate would sensibly help the WG to move forwards and
evaluate all tracks to solve the issues that have been raised.

I would feel more comfortable if we adopted TLS based on real solutions to
real issues than based on personal preference.

Right now several improvement suggestions seem to have solidly been dismissed
with arguments like "won't work".

> screed, but suffice to say that I don't share your opinion of what has

Considering what I saw in private mails from people who don't even dare
post to the list about how they feel this WG is paralyzed, I'm sure that
Greg's opinion is at least shared by other people ;-)

Thanks,
Willy

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 10:32:53 -0800

On Tue, Dec 21, 2010 at 10:22 AM, Willy Tarreau <[email-masked]> wrote:

> > > > out of sync with the stream and from time to time getting in sync
> just to
> > > annoy
> > > > us.
> > >
> Eric, I don't think it's necessary to adopt that tone.

Oh please. The tone problem here is from you and Greg ("paralysed by the
fear", etc.)
I am merely responding in kind.

> In my opinion,
You must be thinking of someone else, since I've never said any such thing.

> sure someone could deliberately write one such thing to prove me wrong but
No, the point is that you and Greg seem to think that claiming "no ordinary
proxy
would actually behave this way" is an argument. It's not.

> evaluate all tracks to solve the issues that have been raised.

This is an example of the tone you think is appropriate? Accusing me of
intellectual
dishonesty? Feel free to apologize at any time.

Regardless of what "we all know", I don't actually care that much whether
TLS is used here,
as evidenced by the fact that I can't be bothered to write up an NPN-based
handshake. IMO
it's marginally easier to analyze but I consider both the proposal in Adam's
draft and the
proposal in our paper to be quite acceptable. No doubt there are many others
that would
also be fine.

> Greg's opinion is at least shared by other people ;-)

Ah yes, the old "I'm getting a lot of support off-list" argument. Always a
classic.

-Ekr

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 19:46:56 +0100

On Tue, Dec 21, 2010 at 10:32:53AM -0800, Eric Rescorla wrote:
> proxy would actually behave this way" is an argument. It's not.

Then let me claim that some proxies might exist which will not expect to
find random-looking traffic and which might switch to any unexpected
behaviour among which automatically switching to TLS and trying to
terminate the stream themselves, crash or even try to execute code
from the binary stream.

We can imagine anything, but if we're talking about a component which is
able to find a second request and a second response in an HTTP stream, it
has minimum messaging compliance requirements to be able to spot a second
request and a second response. Those requirements are incompatible with a
number of the possible implementation bugs that have been opposed to
various proposals.

And that's what Dave Cridland tries hard to explain with his second
CONNECT request too : if the component is able to find a second request,
let's make it find one so that it fails.

> I consider both the proposal in Adam's draft and the proposal in our
> paper to be quite acceptable.

1 host == 1 IP address is not acceptable in 2010. That's one of the reasons
I'm saying that considering reality a bit is needed.

> Ah yes, the old "I'm getting a lot of support off-list" argument. Always a

Sorry for this classic, though I've not said "a lot" but "some". Feel free
to believe I'm making it up if you like, anyway it does not matter.

Willy

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 10:50:21 -0800

> terminate the stream themselves, crash or even try to execute code

I have no idea why you think this is relevant.

> number of the possible implementation bugs that have been opposed to

Again, I have no idea what you are talking about.

> I'm saying that considering reality a bit is needed.

Huh? I have no idea what you are talking about. That is not required by
either the
NPN proposal or the one in our paper.

> to believe I'm making it up if you like, anyway it does not matter.

I don't care if you're making it up. It's simply not relevant to the
discussion in any
way. People who don't speak up don't get counted.

-Ekr

---

From: John Tamplin <[email-masked]>
Date: Tue, 21 Dec 2010 13:52:59 -0500

> I'm saying that considering reality a bit is needed.

I would assume SNI would be used, and surely any SSL implementation that
supported NPN would also support SNI, since it has been a standard for a
while (even OpenJDK trunk has minimal support for it - it just isn't in any
shipping version AFAIK).

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 19:55:13 +0100

> while (even OpenJDK trunk has minimal support for it - it just isn't in any

But for large scale deployments it means you have to terminate the SSL
stream at the border which is not always acceptable.

Willy

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 19:58:51 +0100

> Oh please. The tone problem here is from you and Greg ("paralysed by the

Dude!

I stand by that statement and I certainly did not intend that email to
convey any ill tone (and explicitly said so).
But if my choice of  language has caused offence, then I apologise.

YEt I do not retract the sentiment expressed. Progress has been
stalled by concern about  the possible existence of intermediaries for
which there is currently no evidence that they exist.  However, as I
said in that email, that expression is not meant as a criticism of
those raising the concerns, and I went on to say that since we can't
prove they don't exist then we may as well proceed assuming that they
do,  so long as we can mitigate the costs.

I'm actually arguing in favour of your proposal to have masking, even
though I'm not 100% convinced that it is necessary.

> I am merely responding in kind.

so we are developing a protocol for  push and shove  then?

---

From: Maciej Stachowiak <[email-masked]>
Date: Tue, 21 Dec 2010 11:37:58 -0800

On Dec 21, 2010, at 10:58 AM, Greg Wilkins wrote:

> which there is currently no evidence that they exist.  

The other point of view is that progress has been stalled because some prioritize HTTP semantics and server-side implementation convenience over security against cross-protocol attacks. In my view security is a must-have and the other points are nice-to-haves. Many proposals have been made for how to meaningfully improve security, of these, zero have been adopted, because they supposedly violate HTTP semantics or they might be harder to implement in Java, or whatever.

A more balanced view would be that we have constituencies with different values and priorities, that have so far been unable to come to consensus. We need to find some way to get past that, or this standards process will fail.

Regards,
Maciej

---

From: Gabriel Montenegro <[email-masked]>
Date: Tue, 21 Dec 2010 20:15:58 +0000

It seems to me that some folks may still be a bit confused about CTR mode. It's a different beast than the more common CBC mode, it won't grow the payload. Since it uses XOR,  the cipher text is the same size as the plaintext. It is also much more efficient than CBC mode, although I'm not sure how much. I have an old source that estimates 4x in software and 30-100x in hardware. From the AES competition days:

http://research.cyber.ee/~lipmaa/papers/lrw00/ctr.pdf

Eric, perhaps you have a good or more up-to-date pointers and info on CTR mode?

From: [email-masked] [mailto:[email-masked]] On Behalf Of Eric Rescorla
Sent: 20 December, 2010 16:37
To: Greg Wilkins
Cc: [email-masked]
Subject: Re: [hybi] Handshake security proof

On Mon, Dec 20, 2010 at 4:32 PM, Greg Wilkins <[email-masked]<mailto:[email-masked]>> wrote:

Again, why?

Doing the masking is incredibly trivial by comparison to (for instance) the handshake state
machine. I just don't see the benefit of complicating the protocol for this. What resource
are you conserving?

-Ekr

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 21:16:13 +0100

Maciej,

On 21 December 2010 20:37, Maciej Stachowiak <[email-masked]> wrote:
> The other point of view is that progress has been stalled because some prioritize HTTP semantics and server-side implementation convenience over security

HTTP compliance has been put to a consensus call and was agreed.   It
really is not helpful to criticise those that want to respect that.

But fundamentally it is an error is to see this as a battle between
HTTP compliance and security.   The two are not mutually exclusive and
both are must haves.

> Many proposals have been made for how to meaningfully improve security, of these, zero have been adopted, because they supposedly
>  violate HTTP semantics or they might be harder to implement in Java, or whatever.

and counter proposal have been made that improve security without
violation of HTTP semantics.  OK some of these have been
insufficiently secure for all concerned, but there is progress and the
proposals are being refined. For example, I currently have not seen
any security issues or HTTP issues raised against  Upgrade+masking

> A more balanced view would be that we have constituencies with different values and priorities,
> that have so far been unable to come to consensus.
> We need to find some way to get past that, or this standards process will fail.

I could not agree more.  We need to find a way to bridge between the
constituencies.  A good start towards that would be to accept that the
concerns of the other constituency might indeed be valid (and not just
 "implementation convenience" ). And those that doubt the existence of
vulnerable intermediaries, need to accept that many in the browser
community want to protect against them regardless - so we need to say
which of the defences (TLS+NPN, bogus hosts, masking, CONNECT, etc)
are acceptable.

Currently as Bjoern originally pointed out,  masking has the least
objections and we've been making some progress on making masking
acceptable and overcoming the efficiency concerns raised.   But now
the security emphasis has suddenly switched back to TLS+NPN, despite
strong objections and apparently masking is not good enough??

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 12:23:57 -0800

On Tue, Dec 21, 2010 at 12:16 PM, Greg Wilkins <[email-masked]> wrote:

> ]]

I can't speak for Ian, but as I've now said several times, I consider the
proposal
in our paper to be acceptably secure. My understanding is that Ian reraised
NPN
as an attempt to get past the difficulty we are having resolving the
handshake
issue.

-Ekr

---

From: John Tamplin <[email-masked]>
Date: Tue, 21 Dec 2010 15:28:00 -0500

On Tue, Dec 21, 2010 at 3:15 PM, Gabriel Montenegro <[email-masked]>wrote:

> It seems to me that some folks may still be a bit confused about CTR mode.
> It’s a different beast than the more common CBC mode, it won’t grow the
> payload. Since it uses XOR,  the cipher text is the same size as the
> plaintext. It is also much more efficient than CBC mode, although I’m not
> sure how much. I have an old source that estimates 4x in software and
> 30-100x in hardware. From the AES competition days:
>

AFAIK, AES-CTR doesn't solve the problem without adding a per-frame key.

Assume an attacker wants to get a chosen ciphertext string on the wire,
which will be used to attack a vulnerable intermediary.  Since the attacker
also controls the server in this case, the attacker has the key used to
encrypt the traffic.  Thus, the attacker computes:

pt = AESCTR.decrypt(K, chosenCiperText)

And then sends pt as a WebSocket payload.  When the browser performs
ct=AESCTR.encrypt(K, pt), the attacker's chosen ciphertext now appears on
the wire.

Thus, AFAIK, the only way to combat this is to choose a per-frame random
key, chosen by the browser so the attacker has no advance knowledge of it.

Alternatively, you could use an asymmetric encryption algorithm, but those
are so slow that you generally choose a random session key and encrypt that,
sending it with the session (here, session has to be per frame since the
attacker controls the other end).  However, you just recreated sending a
per-frame key and added no security since the RSA/etc keys have to be known
by examining the packet exchange.

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 21:28:49 +0100

Gabriel,

sorry if this is a dumb question or if I'm missing something... but
with CTR mode, is it correct that you send a key once and then it is
used to generate a sequence of values that are used to XOR the
payloads of frames.

If so, I don't see how this can protect from the attack we are
concerned about, because the attacker controls the server and thus
will be told the key and will be able to predict the encoding of
future blocks.   This can be communicated via other channels to the
browser, which can then send text that will be encoded to plain text.

Surely the only way we can protect against this attack is for a random
key to be generated for every frame and for that key to be sent with
each frame, so that the server is unable to predict the encoding used
on subsequent frames.

---

From: John Tamplin <[email-masked]>
Date: Tue, 21 Dec 2010 15:30:35 -0500

> as an attempt to get past the difficulty we are having resolving the

I assume you would also find Dave's proposal of GET+Upgrade followed by
CONNECT acceptable, if combined with masking on client->server?

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 12:51:00 -0800

I suspect so, but I haven't studied it carefully so I can't say for sure
until I do.

-Ekr

On Tue, Dec 21, 2010 at 12:30 PM, John Tamplin <[email-masked]> wrote:

>> in our paper to be acceptably secure. My understanding is that Ian
>> reraised NPN

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Dec 2010 12:51:35 -0800

> AFAIK, AES-CTR doesn't solve the problem without adding a per-frame key.
Yes, that is correct.

-Ekr

---

From: Gabriel Montenegro <[email-masked]>
Date: Tue, 21 Dec 2010 21:02:02 +0000

On Tue, Dec 21, 2010 at 12:28 PM, John Tamplin <[email-masked]<mailto:[email-masked]>> wrote:
On Tue, Dec 21, 2010 at 3:15 PM, Gabriel Montenegro <[email-masked]<mailto:[email-masked]>> wrote:
It seems to me that some folks may still be a bit confused about CTR mode. It's a different beast than the more common CBC mode, it won't grow the payload. Since it uses XOR,  the cipher text is the same size as the plaintext. It is also much more efficient than CBC mode, although I'm not sure how much. I have an old source that estimates 4x in software and 30-100x in hardware. From the AES competition days:

Yes, that is correct.

Gab: yes, I incorrectly said "payload" when I meant to clarify a point someone (can't remember who) made on this mailing list that they plaintext might grow. Plaintext won't, but payload will, of course, due to the per-frame key. In their paper, Eric, Adam et al estimate that a per-frame key of even 8 bytes is probably enough. I don't know how to arrive at a reasonable key size, though.

---

From: Maciej Stachowiak <[email-masked]>
Date: Tue, 21 Dec 2010 13:41:26 -0800

> really is not helpful to criticise those that want to respect that.

We also have consensus that security is a requirement. The challenge is in working out the details of what such broad statements mean.

> HTTP compliance and security.   The two are not mutually exclusive and

I do not think they are mutually exclusive in principle, but there have been conflicts in specific cases.

> any security issues or HTTP issues raised against  Upgrade+masking

It seems like Upgrade+masking was only raised in the past few days. It does tentatively seem like a security improvement. If anyone can write this approach up in detail, I'll gladly add it to the wiki. (Note that masking obviates the need for hello frames, so Upgrade+hello would not be a useful step in the direction of Upgrade+masking).

> strong objections and apparently masking is not good enough??

I personally think masking is fine, though much depends on the details of the masking and the handshake. I suspect that most who are ok with TLS+NPN are also ok with (some form of) masking-based defense. It seems to me that there are still live objections to masking, at least to strong, crypto-based masking.

Regards,
Maciej

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 21 Dec 2010 23:02:21 +0100

> We also have consensus that security is a requirement. The challenge is in working out the details of what such broad statements mean.

What this means is that proposals that are shown as non-compliant can already
be dropped and the ones that have not yet been shown as insecure can still be
studied.

> I do not think they are mutually exclusive in principle, but there have been conflicts in specific cases.

In fact, the least compliant you are to the underlying protocol, the least
secure you can be. Relying on corner cases means that you'll trigger the
widest range of unexpected behaviours from various implementations.

However, as has been shown, compliance alone is not enough. The right way
to work in my opinion it to maintain compliance, and find how to get the
remaining cases behave in an secure way (eg by failing in a predictable
way).

> It seems like Upgrade+masking was only raised in the past few days.

No, it was raised on this list 3 weeks ago by Roy Fielding :

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

And before that, it was proposed by Roderick Baier in September, on
the subject of covering against cross-protocol attacks :

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

We only need to ensure that the client cannot write something that
can be parsed as a controllable HTTP request where an intermediary
might expect it. For sure masking can be one of the solutions even
if it was first proposed to address a different problem.

Regards,
Willy

---

From: Greg Wilkins <[email-masked]>
Date: Tue, 21 Dec 2010 23:24:17 +0100

On 21 December 2010 22:41, Maciej Stachowiak <[email-masked]> wrote:
>  (Note that masking obviates the need for hello frames, so Upgrade+hello would not be a useful step in the direction of Upgrade+masking).

Maciej,

There is definitely a use for Hello frames, even with masking.
Please read the case for Hello frames, which is not dependent on any
security arguments:

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

In summary, Hello frames are there to check a channel has been created.

---

From: Roberto Peon <[email-masked]>
Date: Tue, 21 Dec 2010 22:36:39 -0800

I'd be happy to see the mask rotate, or perform other cryptographic feats
(AES, etc).
gzip without the multiplexing extension is non-starter to me. I'd have a cow
over the memory requirements of that many simultaneous gzip sessions.
-=R

On Tue, Dec 21, 2010 at 12:15 PM, Gabriel Montenegro
<[email-masked]>wrote:

> *From:* [email-masked] [mailto:[email-masked]] *On Behalf Of
> *Eric Rescorla
> *Sent:* 20 December, 2010 16:37
> *To:* Greg Wilkins
> *Cc:* [email-masked]
>
> *Subject:* Re: [hybi] Handshake security proof
>
>
>
>
>

---

From: Jamie Lokier <[email-masked]>
Date: Wed, 29 Dec 2010 21:33:29 +0000

Eric Rescorla wrote:
> 
>    On Mon, Dec 20, 2010 at 4:32 PM, Greg Wilkins <[1][email-masked]>
>    wrote:
> 
>    On 21 December 2010 00:45, Jamie Lokier <[2][email-masked]>
>    wrote:
>    Doing the masking is incredibly trivial by comparison to (for
>    instance) the handshake state machine. I just don't see the
>    benefit of complicating the protocol for this. What resource are
>    you conserving?

It depends on the type of masking.  If it's trivial, anything can do
it, but gzip and TLS masking aren't trivial.

In the case of gzip, memory.

In the case of TLS, more memory, substantial code size, and
libraries/implementation complexity that may not be readily
available/licensed on some platforms.

The per-connection state for normal gzip compression is noticable.
substantial.  Someone quoted 300k, but I doubt it is that large.

This probably doesn't matter if you have just _one_ connection; only
when you have more.

TLS has similar memory overhead as far as I know, and the TLS code
size can easily be an order of magnitude larger than the application
using it, for small applications.  This doesn't matter on a normal PC,
but it's an issue for small devices, particularly as those often
sometimes don't support shared libraries either.

In contrast the connection state for plain TCP is typically (a) pooled
among multiple connections by the OS kernel, and therefore very low
for mostly-idle connections, (b) typically maximises at 64k if the TCP
is sending and receiving constantly and large/dynamic windows aren't
enabled, and (c) can be limited to as low as about 8k if you really
need on a small device.

Deliberately selecting a small TCP buffer is quite reasonable for
WebSocket usages where you transfer virtually no data - just use it
for server-driven event notifications and small updates.

On a big web server, you might deliberately reduce the TCP buffer size
to support more active users with event-driven connections for a given
amount of RAM.  This is more applicable to WebSocket than HTTP:
because you might know your WebSocket application does not send any
large objects in either direction.

Of course we could just decide that WebSocket spec is not intended for
low-footprint usages.

It would be a shame, in my opinion, as WebSocket would be just as
useful for interactivity on tiny web servers as large ones (think of
your home router's status monitoring page), and because I think if
WebSocket is widely adopted, many useful services will likely become
_only_ available over WebSocket, so affecting resource constrained
clients.

It has been mentioned that in a data centre server context, TLS
offloading hardware is widely used.  I'm not sure if that's true (I've
never used it in any application), but assuming it is, something that
wasn't mentioned is that WebSocket-dependent applications are expected
to maintain at least one open connection per active client, and
possibly several connections, whereas HTTP-over-TLS can use fewer
connections than active clients.  I don't have any idea if requiring
TLS masking would increase the data centre hardware cost of large
WebSocket services for that reason; it's something to consider though.

-- Jamie

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 30 Dec 2010 00:45:13 +0300

> This probably doesn't matter if you have just _one_ connection; only

Yes, I'm suggesting neither TLS nor gzip, but rather the AES-CTR masking in
our paper.

-Ekr

---

From: Jamie Lokier <[email-masked]>
Date: Thu, 30 Dec 2010 01:44:09 +0000

Alexander Philippou and Greg Wilkins discussed using gzip as a masking
mechanism, and making it optional, respectively.

Jamie Lokier wrote:
>> It depends on the type of masking.  If it's trivial, anything can
>> do it, but gzip and TLS masking aren't trivial.

Eric Rescorla wrote:
> Yes, I'm suggesting neither TLS nor gzip, but rather the AES-CTR
> masking in our paper.

The comments about using an optional extension to implement the
masking, and about small-memory clients preferring it to be optional,
were in reference to gzip and earlier TLS suggestions.

I don't see a problem using AES-CTR for it from a resources point of
view - although I also don't see the point.

If the entire conversation is to be weakly encrypted after the initial
handshake, then I especially don't see a point.  HMACs are more useful
if the objective is to avoid accidental corruption by intermediaries;
proper TLS is necessary if the objective is to be secure; and AES,
though strong, can output short ASCII sequences with too high
probability to provide consistently solid armouring.  ('GET ',
case-insensitive, will occur at the beginning of every 1 in 2^29
transmissions... not close enough to zero to call it consistent and
thus be worth the complexity, imho.  Simply transmitting any non-ASCII
sequence would probably be stronger...)

All the best,
-- Jamie