Re: Feedback on WebSocket API, Editor's Draft 13 November 2009.

On Mon, Feb 1, 2010 at 10:47, Ian Hickson <ian@hixie.ch> wrote:
> On Sun, 31 Jan 2010, Sebastian Andersson wrote:
>> On Sat, Jan 30, 2010 at 10:31, Ian Hickson <ian@hixie.ch> wrote:
>> > Right now, today, if I were to expose a WebSocket service on my
>> > Dreamhost shared server, I could do so without any trouble. If we used
>> > a scheme such as the one described above using a policy file, anyone
>> > else also hosting their site on the same server could grant access to
>> > my server to their scripts on their page. Whether this is a technical
>> > or administrative issue, it's an issue we have to handle today.
>>
>> If you only allow the policy file from being read from a single port
>
> How would we do that?

I think it is pretty obvious. Do it like Silverlight! The policy file
is downloaded from port 943. If it is not available there, you have no
right to connect to this IP number.

How do you protect your Web Socket service from another user on your
shared host? They can publish flash clients and java applets that
connects to your server and present any origin they want.

>> > IMHO, yes. I understand that security is a tradeoff between risk and
>> > reward, but fundamentally, it seems to me that it is far off the
>> > "risk/reward" scale to design a system in such a way that a security
>> > problem cannot be fixed when it is discovered. Having the user agent
>> > cache the security policy and act on that cached version even after a
>> > security problem has been found prevents security problems from being
>> > fixed in a timely manner.
>>
>> Sure, it would cause a downtime
>
> We should not design our protocol in such a way that a configuration
> mistake in a security policy can only be fixed by forcing downtime on
> existing users.

But a mistake in the policy file is not enough. The administrator must
make a mistake when writing the policy file, there must be some
malicious code together with users that run the code together with a
service that has a vulnerability running on the same server to get a
problem. If all these things are combined, then you may need some
downtime to fix it (and while you are at it, patch/reconfigure the
service that was vulnerable to protect against native malware of the
same kind).

With a configurable timeout value in the policy file (which is lacking
in flash's policy files, yet they are cached for some time), then the
administrator could even decide what is right for their site.

I think you worry too much about a problem that most administrators
already have to face when deploying java, flash or silverlight
solutions, so they should already be aware of it.

>> With the Web Socket protocol:
>> - Existing services would have to be changed if they should be
>> accessible (with the risk of bugs, duplication of existing access
>> control and logging).
>
> This is intentional, to prevent pages from abusing existing services.

Yes, it was intentional, but it is still a drawback. For me it
prevents all the cases where I would want to use the API today
(replacing existing flash solutions without having to make changes on
the server side).

>> - Requires all new services to implement the policy mechanism correctly.
>
> It's pretty trivial to implement.

Yes, but it still has to be implemented correctly in every server.

>> -- Instead of just having a few correct implementations in the clients
>> (that already have code for origin handling and whose designers
>> hopefully are aware of the problems), each server will have to have it
>> with associated risks of errors. A huge potential for new security
>> problems. Will of course be cheaper and less risky when libraries are
>> available for most languages, but still many more implementations.
>
> I don't understand. Why would the servers have it? It's the client that
> enforces the security policy.

>From section 5.1 in the protocol specification:
"Servers that are not intended to process input from any Web page but
   only for certain sites should verify the "Origin" header is an origin
   they expect, and should only respond with the corresponding
   "WebSocket-Origin" if it is an accepted origin"

I think that covers a large proportion of the servers and I think that
most projects would want to implement support for it just to allow
different server deployment scenarios.

>> - Native clients against a new service would have to use the Web
>> Socket protocol too.
>
> If it's a Web Socket subprotocol... then yes. I wouldn't recommend that
> people use this protocol for designing protocols intended to be used by
> native clients other than browsers, though obviously that's possible too.
>
>> -- Adds a little extra cost and risks. Will of course be cheaper and
>> less risky when libraries are available for most languages, but still
>> way more implementations.
>
> Than what? I'm confused. Web Socket is really trivial to implement -- the
> whole point is to make it easy to implement so anyone can do it. It's like
> CGI, intended for anyone to be able to hack something up quickly.

Compared to straight TCP it is more code. You must also read variable
length frames (both in the first http-like response and later), which
in the past has been implemented incorrectly over and over again.

>> What about someone adding support for Basic authentication in their
>> client, exposing the credentials?
>
> I don't understand this point. What does the Web Socket protocol have to
> do with how you design your subprotocol's authentication?

Sorry, I must remember incorrectly because I thought that the Web
Socket protocol could also handle 401 responses, but I see now that it
only supports 407 responses. Did an earlier draft support 401?

> I'm certainly open to suggestions for avoiding this problem, but short of
> introducing random delays, I don't see how to fix it. Unless we force a
> port, which I don't see how we can do, a policy file would have the same
> problem (just use the policy file to do the port scanning).

Both Silverlight and flash uses a standard port to download their
policy file from, so I don't see why Web Sockets can't do the same.

>> - Part of the security of the protocol relies on the fact that the
>> clients can't use "raw" TCP sockets. This is not always true if the
>> client has the flash, java or the Silverlight plugins. What about future
>> plugins or APIs?
>
> What about them?

They can send any "origin" they want and then the security of the
"origin" model of the server goes out the window, given that the
server wants to verify the origin (and I think most would).

>> -- During a transition phase to html5, I would think that people would
>> simulate the Web Socket API via scriptable flash clients since most
>> users already have it installed, so this would probably become rather
>> common. Someone might also do the same via Silverlight.
>
> Actually so far most people have emulated it using XHR.

Yes, but you can't implement it via XHR and you would get a higher
overhead, right? So your new Web Socket service would also have to
serve HTTP for the XHR emulation. Seems like a more expensive solution
compared to a reusable, scriptable flash client implementation. But
perhaps people will use both to get the largest possible audience
while getting the best performance where it is possible?

> Fundamentally, raw sockets plus a policy file is a completely different
> approach than Web Sockets. I would recommend developing a second proposal
> separate from the Web Sockets spec, and approaching browser vendors to see
> if they prefer it.

Ok. Perhaps I'm pessimistic here, but I fear that one important
browser vendor would prefer that raw sockets were not added so their
own competing technology remains a better choice and if the Web Socket
protocol is part of html 5, it is easier for them to just say no. I
hope I'm wrong though.

> Personally I think there are huge problems with offering raw sockets plus
> a policy file that Web Sockets carefully avoids:
>
>  - raw sockets are stream-based, not packet based, which is quite a lot
>   harder to program against (Web Sockets is aimed at both professionals
>   and amateurs, and thus avoids exposing the underlying stream to the
>   authors, since they are likely to trip up authors).

If amateurs can't implement: read length, read "length" bytes, then
they can surely download a javascript library that implements it for
them. Perhaps they could even find a Web Socket protocol library if
they prefer frames with start/end bytes?

>  - raw sockets mean a binary interface, which is not possible natiely in
>   JS currently. It also means exposing authors to the world of character
>   encodings, a hell of momentous proportions (Web Sockets avoids this by
>   being UTF-8-only).

Although a bit inefficient compared to adding new classes, but each
byte in the stream can easily be mapped to characters in the range
U+0000 to U+00FF and then the result is put in a JS string. The string
can easily be created with String.fromCharCode() and the bytes can be
read with charCodeAt(). For pure ASCII protocols, that would add no
extra overhead compared to the Web Socket protocol (and many existing
RFC described protocols use pure ASCII). Of course it could be more
efficient to extend the API with at least methods to write UTF-8 and a
mode were one reads UTF-8 instead of binary. Neither would be hard to
implement in pure JavaScript though (there are plenty of such
implementations already if one googles for it), even though there
would be a slight overhead.

>  - policy files require two network connections to set up a socket (Web
>   Sockets is specifically designed to avoid ever using more than one).

With caching, that is only a problem for the first connection and with
repeated connections, the request/response answer adds more overhead
in the Web Socket case.

>  - policy files are hard to do right, e.g. either you force a specific
>   port and policy mechanism, or you open yourself to shared-hosting
>   attacks, upload attacks where the attack causes a policy to be uploaded
>   to a victim site, and other problems which have plagued Flash for
>   years. (Web Sockets sidesteps all of this by not using policy files.)

But the problem has already been solved by Adobe and Microsoft. The
implementation is not that hard and it only needs to be done by a few
browser vendors, not a whole lot of servers.

>  - raw sockets means we can't address multiple services per port. (Web
>   Sockets supports this natively.)

That can be done with higher level protocols, just like the Web Socket
protocol has shown (and other protocols before it).

>  - raw sockets means authors have to do host-rebinding protection. (Web
>   Sockets protects against this natively.)

And the policy file solves that.

>  - mistakes in a policy file can lead to serious but undetected attacks,
>   e.g. spammers using local SMTP servers. (Web Sockets prevents use of
>   SMTP servers entirely.)

So can native malware and you already have to deal with it. In this
case the answer is simple, write correct policy files! If I configure
my firewall incorrectly, I don't blame the IP protocol. Why should I
blame the capabilities of the web browser if I wrote an incorrect
policy file?

One can also add another layer of protection like the Silverlight
implementation has done and only allow connections to a limited range
of port numbers. Existing services can be published via port number
translation so it really doesn't hinder anything in practice.

Regards,
/Sebastian
-- 
One laptop per child project: http://laptop.org/

Received on Monday, 1 February 2010 16:27:01 UTC