Subject: [hybi] Full Frame Masking

From: Bob Gezelter <[email-masked]>
Date: Wed, 06 Apr 2011 06:31:24 -0500

It is a measure intended to befuddle pre-existing intermediaries, to wit
(from the -06 specification):

"4. Data Framing

  4.1. Overview

  In the WebSocket protocol, data is transmitted using a sequence of
  frames. Frames sent from the client to the server are masked to
  avoid confusing network intermediaries, such as intercepting proxies.
  Frames sent from the server to the client are not masked. ..."

I see no differential advantage to limiting the masking. Since the key to
unmasking the data is contained in the stream, clearly only those
intermediaries not cognizant of the WebSocket protocol will be befuddled.

- Bob
+--------------------------------------------------------------------------+
| Robert "Bob" Gezelter                       E-Mail:  [email-masked]  |
| Robert Gezelter Software Consultant                                      |
| 35-20 167th Street, Suite 215               Fax:       (on Request)      |
| Flushing, New York  11358-1731                                           |
| United States of America                    http://www.rlgsc.com         |
+--------------------------------------------------------------------------+

---

From: Andy Green <[email-masked]>
Date: Wed, 06 Apr 2011 12:42:31 +0100

On 04/06/2011 12:31 PM, Somebody in the thread at some point said:

Hi -

> intermediaries not cognizant of the WebSocket protocol will be befuddled.

You are right.  However, that was the reasoning for the munging.

The concept is there may exist http intermediaries that do a crappy job 
and do not understand websockets either.  For these guys, it's claimed 
it may be possible to craft websocket traffic that is valid websocket 
traffic, but is understood by the broken intermediary to be http, thus 
poisioning its cache with whatever you like.  Further in this scenario, 
clientside javascript is able to send the websocket traffic with the 
crafted content.

Well, some people believe that and some people don't.  The point become 
moot about what anyone believed when Mozilla pulled websocket support 
over this issue.

Munging the packets so the javascript can't craft the content on the 
wire was the resulting workaround, really a workaround for getting 
support pulled from a major browser rather than directly any 
identifiable, reproducible technical issue.  But that issue, Mozilla 
support, is very real.

-Andy

---

From: David Endicott <[email-masked]>
Date: Wed, 6 Apr 2011 10:00:26 -0400

> moot about what anyone believed when Mozilla pulled websocket support over
> this issue.
>

I thought Mozilla's concern was related to the -75/76 spec that had the
"magic-key" in the HTTP body payload of the handshake, but didn't include a
"Content-Length" field - thus intermediaries (proxies/firewalls) sometimes
would hang, waiting for the HTTP connection to close and end the request.

If I'm mistaken and it really was about WS payload masking (and please don't
make me spelunk the archives again) then, well, I'll just have to shake my
head sadly.   In the absence of a demonstrated issue we should have pushed
back a little harder.   But I understand (and support) the need to get all
the major client-agent vendors on board.

If we really *are* trying to not upset intermediaries that are doing traffic
inspection then we probably should mask in both directions, shouldn't we?

(Of course, I stand by my opinion that once the TCP connection has been
established via the HTTP Upgrade handshake, any intermediary that confuses
itself with traffic on that pipe is a broken intermediary and not our
concern.)

---

From: Andy Green <[email-masked]>
Date: Wed, 06 Apr 2011 15:17:10 +0100

On 04/06/2011 03:00 PM, Somebody in the thread at some point said:

Hi -

> "magic-key" in the HTTP body payload of the handshake, but didn't
> include a "Content-Length" field - thus intermediaries
> (proxies/firewalls) sometimes would hang, waiting for the HTTP
> connection to close and end the request.
>
> If I'm mistaken and it really was about WS payload masking (and please
> don't make me spelunk the archives again) then, well, I'll just have to
> shake my head sadly.   In the absence of a demonstrated issue we should
> have pushed back a little harder.   But I understand (and support) the
> need to get all the major client-agent vendors on board.

http://news.cnet.com/8301-30685_3-20025272-264.html

Still waiting to hear which brand of proxy is meant to experience this 
or hear it is reproduced.  Frankly it's a bit like it suits everyone to 
not to try to reproduce it in case the lack of results might be 
embarrassing.

> If we really *are* trying to not upset intermediaries that are doing
> traffic inspection then we probably should mask in both directions,
> shouldn't we?

The hysteria was all about the specific claim, so they only considered 
that a proxy might be fooled into seeing a GET from its client side.

> established via the HTTP Upgrade handshake, any intermediary that
> confuses itself with traffic on that pipe is a broken intermediary and
> not our concern.)

No argument from me.  But what is clear is that this is now baked into 
the history of the protocol there is no point arguing against it once 
you realize it is not there for technical reasons.

One way to look at it is we are better off reaching a successful 
conclusion of the spec with this 'spec parasite' thing in it than 
destabilizing the group pointlessly and delaying or destroying the whole 
effort to try to get rid of it.  (At one point they wanted AES 
encryption which would have rendered the whole protocol out of reach of 
weak targets, but actually the recycling XOR frame key is just annoying, 
not deadly.)

-Andy

---

From: David Endicott <[email-masked]>
Date: Wed, 6 Apr 2011 11:01:27 -0400

> Still waiting to hear which brand of proxy is meant to experience this or
> hear it is reproduced.  Frankly it's a bit like it suits everyone to not to
> try to reproduce it in case the lack of results might be embarrassing.

*"We don't demand solid facts. What we demand is a total absence of solid
facts. I demand that I may, or may not, be Vroomfondel."*

>
>  (Of course, I stand by my opinion that once the TCP connection has been...
>>
>

> No argument from me.  But what is clear is that this is now baked into the
> history of the protocol there is no point arguing against it once you
> realize it is not there for technical reasons.
>
> One way to look at it is we are better off reaching a successful conclusion
> of the spec with this 'spec parasite' thing in it than destabilizing the
> group pointlessly and delaying or destroying the whole effort to try to get
> rid of it.  (At one point they wanted AES encryption which would have
> rendered the whole protocol out of reach of weak targets, but actually the
> recycling XOR frame key is just annoying, not deadly.)
>
> Agreed.  I'm highly motivated to have a workable final spec. completed,
warts or no warts.

I'm willing to let any aspect of the spec. pass if it doesn't impair
functionality.  (Hence my discomfort with the close commingling/overlap of
HTTP Upgrade & WS handshake as I think it impairs functionality).    On the
other hand, things like Sec-Websocket-Key and frame masking are, in
my opinion, useless.   But since it's mostly harmless, I don't care and it's
implementable easily enough.

I have a young daughter and if she wants an asynchronous interactive Elmo,
then gosh darn-it, I'm going to help make that happen.    Oh, and ya, my
employers have been waiting years for "server-push" to the browser, but
whatever.

---

From: John Tamplin <[email-masked]>
Date: Wed, 6 Apr 2011 11:16:31 -0400

> try to reproduce it in case the lack of results might be embarrassing.

The nature of a transparent proxy means it can be hard to even detect its
presence, let alone what brand and software version it is.

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

---

From: David Endicott <[email-masked]>
Date: Wed, 6 Apr 2011 11:45:43 -0400

Has anyone demonstrated an actual instance of a problem so far, either as
revealed during WS implementation testing or from targeted
vulnerability assessment?

Does anyone have a suspicion that a particular vendor's product might be at
risk?

(Not snark, just curiosity.)

---

From: Jamie Lokier <[email-masked]>
Date: Wed, 6 Apr 2011 20:55:27 +0100

David Endicott wrote:
>    Oh, and ya, my employers have been waiting years for
>    "server-push" to the browser, but whatever.

People have done that for about 12 years over HTTP, so WebSocket does
not add new functionality here.  It's just an optimisation, and in
many cases, WebSocket will be slotted into an existing framework that
already works over HTTP (assuming WS works better).

-- Jamie

---

From: Roberto Peon <[email-masked]>
Date: Wed, 6 Apr 2011 12:56:52 -0700

Server push over HTTP?
We have poor emulations of it, but we've never had it in HTTP.
What are you thinking about w.r.t. server push Jamie?

-=R

On Wed, Apr 6, 2011 at 12:55 PM, Jamie Lokier <[email-masked]> wrote:

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

---

From: David Endicott <[email-masked]>
Date: Wed, 6 Apr 2011 16:10:16 -0400

No, I mean *real* server push.   The synchronous nature of HTTP has not
allowed "real-time" asynchronous updates from the server.    No matter how
clever we've been so far (AJAX long polling, et al.) the slight latency has
been an issue.

We do live financial market trading at the inter-dealer level (ie. our
customers are banks) and *any* latency is bad latency.   Yes, seriously.
Being able to implement an asynchronous callback like mechanism is going to
allow us to leverage the browser as viable UI tool.

We do not view WS as an optimization that slots into existing frameworks -
we view it as a new protocol mechanism separate but allied with HTTP.

Our planned use cases have WS as the transport for a message based API.
The browser will use HTTP to fetch HTML/CSS/JS to produce UI rendering.   In
several cases our WS server will sit on a different machine & port than the
HTTP server (subdomains to satisfy same-origin policy).   In a couple of
other cases it'll be part of a WSGI application and integrated into the HTTP
stack.

---

From: Brian <[email-masked]>
Date: Wed, 6 Apr 2011 13:45:30 -0700

> other cases it'll be part of a WSGI application and integrated into the HTTP

The origin enforcement is mediated by the server in websockets, which
allows the server to accept connections from any arbitrary domain at
its discretion.  The method for which origins to allow is
application-specific.  You can host your websocket server on any
arbitrary domain, and connections will be allowed as long as the
server responds with a Sec-Websocket-Origin header that matches the
domain that served the HTML/JS that is attempting to initiate the
connection.

Brian

---

From: Willy Tarreau <[email-masked]>
Date: Wed, 6 Apr 2011 23:09:45 +0200

Hi David,

> vulnerability assessment?

No, but see below.

> Does anyone have a suspicion that a particular vendor's product might be at

Not a particular vendor either. The problem is that it has been proven via
an experience that some unidentified products behave badly when subjected
to WS-like traffic. Those products could not be identified because they're
likely transparent proxies. By "behave badly", I mean things like connection
resets and truncated responses (which can themselves be caused by connection
resets BTW). Since it was not possible to identify those products, we had
to try to guess what types of issues they might suffer from, with some very
likely ones that affect real products to the most unlikely ones that affect
no yet-known product.

The actual masking was proposed as a solution against a risk of exploiting
this family of issues in these products, by still taking into account the
risk of ever encountering an affected product, the possible impacts, the
performance costs and the flexibility cost.

The masking method will never be perfect by definition, because :
  1) it's still weak in front of the most possibly vulnerable product we
     could think of ;
  2) it's useless and expensive for the vast majority of non-vulnerable
     products ;

Yet it's still well balanced, it's far less expensive than solutions that
could cover everything we can think of (possibly at the expense of limiting
protocol adoption in some environments), and it's very efficient against
all the vulnerabilities we could *reasonably* think of (based on experience
and the difficulty to implement those vulneratbilities on purpose).

It could probably be better for some uses at the expense of other ones, may
be we could make it better for more uses, but given the amount of arguments
everyone has made here on the subject here, I think that many aspects have
been covered.

It's a fact that I think that moving the masking after the framing would
simplify it a bit by avoiding code duplication and state keeping, and make
it possible to propose other forms of masking later, but I agree that these
are acceptably small benefits, and I respect the fact that some people have
fears about the more controllable data that appears after the two first
bytes, even if I don't share them based on my experience with HTTP
implementations.

What we should do now is to see what it costs to correctly implement the
masking as it is now, what it could have cost to implement it differently,
what either choices bring in terms of flexibility, and decide if the
benefits are worth the arguably small added risk on the security plan.

Since we can't prove either way is better than the other, we can only make
a choice based on personal experience, evolution perspectives, and feelings.

Hoping this clarifies the situation for you,
Willy

---

From: Jamie Lokier <[email-masked]>
Date: Wed, 6 Apr 2011 22:12:45 +0100

Jamie Lokier wrote:
>> People have done that for about 12 years over HTTP, so WebSocket
>> does not add new functionality here.  It's just an optimisation,
>> and in many cases, WebSocket will be slotted into an existing
>> framework that already works over HTTP (assuming WS works
>> better).

>    What are you thinking about w.r.t. server push Jamie?

Server push means the ability to send messages to the client when the
server has a message to send, without polling, after the client has
established a connection for this purpose.

If it works reasonably well, it exists regardless of how it's
implemented.  (WebSocket is not without hacks either.)

Functionally, Cometd, Bayeaux, numerous others, provide much the same
effect as WebSocket, and applications using them are unlikely to
notice the difference.  Not even in resources used.  WS may be faster
for some applications, but not hugely so.

The practical difference is WebSocket uses fewer TCP connections
(though slower handshake), is a bit simpler, a bit faster, and it's
built in to some browsers so you don't have to load as much
Javascript.  Hence: an optimisation.

If someone is waiting for server-push before they can write that async
application they dreamed of... well, there is no reason to wait, there
is good software and toolkits to do it already.

If someone thinks WebSocket fixes the complexity, robustness,
performance or even network compatibility problems of the HTTP stuff,
they're mistaken.  (WS appears to be less network compatible, at the
moment.)

There remain complexity, robustness, performance and compatibility
issues with WebSockets.  Robust apps must address them using the same
methods as with HTTP transports - retrying connections, duplicate and
order tracking (across retried connections - corner cases happen),
keepalives, idle timeouts, dropping/coalescing redundant updates,
cooperating between multiple windows/widgets, message target dispatch,
etc. etc. etc.

I expect many robust apps & toolkits will use the same code for that
using either transport method underneath.

And many of the server-side networking and scaling issues are similar
in either case.

WebSocket only replaces part of the server push problem, and it
doesn't introduce any new behaviour we can't already do, that I can see.

I'm glad we have it, it's an improvement (I hope), but I can't think
of any application that's made possible by it.  (Would love examples
if you have any!)

Thanks for listening,
-- Jamie

---

From: Roberto Peon <[email-masked]>
Date: Wed, 6 Apr 2011 14:28:00 -0700

Jamie--

I think your arguments are fair and I agree with most of the points here. In
fact, if I'm communicating clearly, you won't find any disagreements here.

I'm particularly worried about what effect WS will have on.. well,
everything but the user-agent. I've been quiet on that front for a while
because consensus was against including multiplexing, etc., but my silence
doesn't mean those fears are yet addressed. I hope that John's multiplexing
extension whill help to address at least the scaling problems that I fear.

I agree that, as compared to the various hanging-get mechanisms, any
full-duplex protocol can only offer optimizations. I think that the thing to
watch is how important those optimizations are. Using a single host, for
instance, you can't get more than 6/rtt messages per second over current
methods (assuming per-host connection limit of 6). You may be able to work
around this by using more hosts, yes, but barrier to entry for such an
application is higher. Worse, potentially, is that if you're running many
machines at the same IP as many sites do, the various connections end up at
different servers, causing backend loadbalancing complexity that the
aplpication writer must resolve either by additional self-proxying, or by
modifying the loadbalancer.

Anyway, this is OT, and I suspect (or at least hope) that all of this is old
hat, and we're just arguing semantics and otherwise violently agreeing.
-=R

---

From: Jamie Lokier <[email-masked]>
Date: Wed, 6 Apr 2011 22:42:53 +0100

David Endicott wrote:
>    No, I mean *real* server push.   The synchronous nature of HTTP has
>    not allowed "real-time" asynchronous updates from the server.    No
>    matter how clever we've been so far (AJAX long polling, et al.) the
>    slight latency has been an issue.

Exactly: It is an optimisation.  I'm not saying WebSocket isn't an
improvement, and it sounds well suited to your purpose.

You are mistaken if you think HTTP long polling is restricted to a
synchronous model and cannot do continuous asynchronous updates.  It
depends very much on how you go about it.  Obviously if you wait for a
whole response before sending another request, that's what happens.
That's the most well known model, but it's not the only way - there
are several other patterns available, to remove the synchronous delay.

Most people don't care about that delay, so they stick with the
synchronous pattern because it's easy.

You are mistaken if you think WS is latency optimised.  I have brought
up issues affecting TCP latency or proxy latency several times on the
hybi list, and nearly every time, it is ignored in favour of other things.

>    We do live financial market trading at the inter-dealer level
>    (ie. our customers are banks) and *any* latency is bad latency.
>    Yes seriously.

I know.  I'm a latency geek myself.

>    Being able to implement an asynchronous callback like mechanism
>    is going to allow us to leverage the browser as viable UI tool.

For your purpose, WS sounds well suited.

If you have big money critically dependent on absolutely minimising
server-to-browser latency as much as possible, there are better
methods than WS, though you are of course right that WS is a
substantial improvement over HTTP in that area.

>    We do not view WS as an optimization that slots into existing
>    frameworks - we view it as a new protocol mechanism separate but
>    allied with HTTP.

That's fine.  Of course you can implement a 'WebSocket' object in
Javascript that uses HTTP behind the scenes, as your fallback ;-)

>    Our planned use cases have WS as the transport for a message based
>    API.   The browser will use HTTP to fetch HTML/CSS/JS to produce UI
>    rendering.   In several cases our WS server will sit on a different
>    machine & port than the HTTP server (subdomains to satisfy same-origin
>    policy).   In a couple of other cases it'll be part of a WSGI
>    application and integrated into the HTTP stack.

That's a fine plan.

-- Jamie

---

From: Willy Tarreau <[email-masked]>
Date: Wed, 6 Apr 2011 23:45:50 +0200

On Wed, Apr 06, 2011 at 10:12:45PM +0100, Jamie Lokier wrote:
(...)
> of any application that's made possible by it.

I 100% agree with what you said Jamie. That's exactly the reason why I've
been trying to get something *usable* and *cheap* : because that's the
only way it will be adopted, considering that alternatives already exist
and are used every day.

Making a worse/harder to use/more expensive/less extensive replacement
for current technologies will simply not work.

If application developers and users think "Hey, that's really cool", they
will deploy it and the remaining obstacles will be leveraged under the
users' pressure (mainly the incompatible transparent proxies).

But if it does not bring any measurable benefit, why will developers have
to maintain multiple access methods with their share of issues when the
current ones already work ?

I really think that all the remaining points will have to be addressed
at least on the list to ensure that nothing will block their inclusion
later (multiplexing, compression, raw TCP, alternative masking, non-101
responses, authentication, state management between connections). If
we don't do that, we may block extensivity due to stupid design mistakes
and regret it later.

Regards,
Willy

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 7 Apr 2011 09:14:36 +1000

> allow us to leverage the browser as viable UI tool.

I think it is a misconception that WS is going to greatly improve
latency over solutions like long polling.

Firstly this is all over TCP/IP and packets can be lost and timeouts
might be needed to trigger a resend. So no matter what you do you are
looking at a chance of >1s latency on the occasional message - TCP/IP
is not for controlling pace makers!

Long polling does have maximal latency of 3 x network latency, only if
you are unlucky and hit the no poll window or if you are streaming
lots of events.   But for many traffic profiles long polling latency
is 1 x network latency.

So don't get me wrong - WS should be  better for latency, but it is no
silver bullet. Plus as Jamie has pointed out several times, the
obfuscated framing can have a bad effect on latency through
intermediaries.

cheers

---

From: Bruce Atherton <[email-masked]>
Date: Wed, 06 Apr 2011 16:41:30 -0700

> hybi list, and nearly every time, it is ignored in favour of other things.

That brings to mind a question I've been meaning to ask for a while now. 
Given the existence of BufferBloat[1], should Websockets have any 
congestion avoidance mechanism other than TCP?

Among the problems with BufferBloat is that large buffers present on 
most equipment on the Internet defeat the ability for TCP to detect 
congestion in a timely way. This combined with absurd queue lengths can 
result in RTT that seem to travel several lunar distances. There are 
ways to reduce the impact (AQM, ECN) but nothing that will be widely 
used in the next several years, in all likelihood.

So with BufferBloat in mind, should Websockets consider providing its 
own standard congestion control? This wouldn't be part of the base 
protocol, of course, but rather a separate draft. Perhaps something that 
used timings on PING and PONG to do something like TCP Vegas.

I don't have the experience to give a concrete suggestion or even to 
determine whether it is worthwhile or not, but I wanted to bring it up 
for discussion.

[1] 
http://gettys.wordpress.com/2010/12/06/whose-house-is-of-glasse-must-not-throw-stones-at-another/

---

From: Jamie Lokier <[email-masked]>
Date: Thu, 7 Apr 2011 03:30:06 +0100

> is not for controlling pace makers!

It depends on the network.  TCP on wired LANs rarely delays for 1s in
the middle of a regular traffic flow.  But on 3G, it regularly delays
for >20s, and on my old 56k modem, it would sometimes delay for
minutes, recovering from a burst of lost packets.

Whatever it is, it's often several times longer than the time of a
transient network outage.

If you really need consistent minimum latency (like in a video game),
you'd try for one of the quirky ways to access UDP or equivalent;
that's a lot of non-portable work, though.

> lots of events.   But for many traffic profiles long polling latency

I think what David's getting at is inter-message delay _less_ than 1 x
network latency (due to not having to wait for the previous one to be
delivered), and maximal transmission latency close to 1 x network
latency when there _are_ lots of events being streamed.

That can't be done with the simplest (and most reliable) type of
long-polling, where the client requests, server sends a complete
response, client response with another request, server can then send
next response...

But it can be done with other long-polling communication patterns.

-- Jamie

---

From: Joel Martin <[email-masked]>
Date: Wed, 6 Apr 2011 23:30:56 -0500

> of any application that's made possible by it.  (Would love examples

IMO, the lower latency (once established), and more socket-like nature of
WebSockets will enable a whole realm of new web applications. The
combination of fast Javascript engines and WebSockets is what made noVNC (
https://github.com/kanaka/noVNC) possible.

Existing web applications that use AJAX or long-polling may or may not be
helped all that much by the lower latency achievable with a WebSocket
connection. It's the new applications that become possible that are exciting
to me.

Even if the latency of AJAX/long-poll was sufficient for noVNC, I would
never have made the conceptual leap by thinking in terms of HTTP plus a pile
of kludges.

Everybody is excited about the video and audio tags that is part of the next
HTML, but in my opinion the second most important part of the new evolving
open web platform is WebSockets (the first being fast Javascript engines).

Regards,

Joel Martin (kanaka)

---

From: Andy Green <[email-masked]>
Date: Thu, 07 Apr 2011 06:54:18 +0100

On 04/06/2011 10:09 PM, Somebody in the thread at some point said:

Hi -

> Not a particular vendor either. The problem is that it has been proven via

"It has been claimed...", it's not proven to me anyway at all.

> likely transparent proxies. By "behave badly", I mean things like connection

I have already mentioned some weeks ago I would be interested to make a 
fuzzer or other tool in libwebsockets if I get some help with exactly 
what packets it was claimed it needs to send.  Then we could expect to 
'out' the allegedly "badly behaving" intermediaries and I will be able 
to agree it is proven.

You'd think people would be highly interested to run such a security 
tool on their own client side and make sure they are not vulnerable to a 
proposed attack that had such a high public profile and claimed 
apocalyptic results.  Because if they were vulnerable to -76 they are 
still sitting there vulnerable to the same packets issued another way 
from client side.  Surely people would want to know and swap out or 
upgrade that intermediary.

> Yet it's still well balanced, it's far less expensive than solutions that

I agree if you compare it to AES that quite a few people insisted was 
absolutely necessary or it would be The End Of The Internet, then Ian 
Fette balanced those demands well.

-Andy

---

From: David Endicott <[email-masked]>
Date: Thu, 7 Apr 2011 09:34:58 -0400

> implemented.  (WebSocket is not without hacks either.)

Agreed.   Unfortunately, part of what I have to deal with in my situation is
perception.   Having a polling layer as part of the system is anathema to
our firm.   The fact that the performance difference is negligible is
irrelevant.  *Any* impairment of timely message delivery is a concern.
 (Note: our time critical application will be used over a private network,
so Internet latencies are not a factor)

Also, a "true" asynchronous mechanism produces a much cleaner implementation
- without the need for ad-hoc "kludges" to emulate
that behavior from synchronous HTTP.  I must admit certain bias towards
elegance.

> is good software and toolkits to do it already.

We have and we do.   But until the recent arrival of certain new
technologies (WS, CSS2, HTML5 and fast JS engines) using the browser as a
platform neutral User Interface has been....unsatisfactory.

> doesn't introduce any new behaviour we can't already do, that I can see.

Personally, I like how it makes explicit the asynchronous nature of the
communication.   If I had to guess (and that's always risky) - I suspect WS
is going to end up doing content centric API's  (similar to REST) and HTTP
will become presentation centric.   ie. your browser does HTTP to fetch some
HTML/CSS and then uses WS to fill in the content.   And that content can be
dynamically live.

> of any application that's made possible by it.  (Would love examples

True, I doubt there is any application that WS makes "possible", but I'd
argue there are a boatload that would become "practical".