Subject: [hybi] Concerns about Origin

From: "Simon Pieters" <[email-masked]>
Date: Mon, 22 Nov 2010 14:08:35 +0100

One thing I'm concerned about with websockets is that most generic  
websocket servers seem to just echo the Origin value in  
Sec-WebSocket-Origin without giving an obvious way for the app writer to  
restrict which Origins to allow, let alone making it clear to the app  
writer that it is his responsibility to restrict connections from  
different origins.

So people might assume that "websockets uses origin-based security model"  
and go ahead and assume that the browser will disallow connections from  
other origins.

I think the spec should be even clearer that it is the server's  
responsibility to restrict connections from unwanted origins, and that  
browsers will happily attempt to connect to cross-origin websocket  
servers, which in practice will lead to sites being trivially vulnerable  
to attacks from other Web pages. I think it might be good to suggest that  
generic websocket servers should force the app writer to consider which  
origins he wishes to allow connections from.

For instance, in pywebsocket, the default handshake impl echos the origin,  
and the sample app always allows the connection.

http://code.google.com/p/pywebsocket/source/browse/trunk/src/mod_pywebsocket/handshake/handshake.py#196
http://code.google.com/p/pywebsocket/source/browse/trunk/src/example/echo_wsh.py#35

I think it would be better if web_socket_do_extra_handshake required an  
extra parameter (or something) about which origins to allow (maybe with a  
regexp or a list of strings or a string with comma-separated origins with  
a special value like "allow-all-origins").

-- 
Simon Pieters
Opera Software

---

From: Zhong Yu <[email-masked]>
Date: Mon, 22 Nov 2010 10:07:46 -0600

I agree. The spec should *require* servers to actively check Origin
and reject handshake immediately if Origin isn't accepted, instead of
allowing servers to defer that logic to clients.

APIs for server apps should have a hook to the handshake event, so
that apps can participate in the handshake. Apps have an opportunity
here to check Origin, set cookies, etc. per connection.

"Same origin" policy probably would be the most popular/default
policy. A simple and safe way to implement that on server side is to
match "Origin" with "Host" header(or the host part of the ws resource
URI).

That is safe if we assume that all pages on the Host can be trusted.
Cookies don't assume that, they have an additional "path" restriction.
If a WS app is as paranoid, currently it doesn't have a way to know on
which page specifically the connection is made. The app can add its
own anti XSRF measure like what we have to do for HTTP but that's not
too easy.

- Zhong Yu

---

From: "Simon Pieters" <[email-masked]>
Date: Mon, 22 Nov 2010 17:38:52 +0100

> allowing servers to defer that logic to clients.

If the server has a hardcoded Sec-WebSocket-Origin value, I have no  
problem with relying on the client checking that it matches what it sent.  
My problem is with servers just echoing the Origin and the app writer has  
no idea that it allows connections from anywhere.

> here to check Origin, set cookies, etc. per connection.

pywebsocket allows apps to do extra checks in the handshake, but I'd like  
to take a step further and make the origin choice a required step for the  
app writer.

> match "Origin" with "Host" header(or the host part of the ws resource

Host only carries domain and port, not the protocol, and the port for the  
websocket connection can very well be different than the port of the page  
you expect a connection from...

> Cookies don't assume that, they have an additional "path" restriction.

The "path" feature for cookies do not help anything with security, since  
the same-origin-policy allows you to open an iframe within the same origin  
and eat all the cookies.

> which page specifically the connection is made.

That is by design, so that people don't fall into the cookie "path" trap  
and think they're safe when they're not.

> The app can add its

Cheers,
-- 
Simon Pieters
Opera Software

---

From: John Tamplin <[email-masked]>
Date: Mon, 22 Nov 2010 11:58:36 -0500

On Mon, Nov 22, 2010 at 11:38 AM, Simon Pieters <[email-masked]> wrote:
> pywebsocket allows apps to do extra checks in the handshake, but I'd like to
> take a step further and make the origin choice a required step for the app
> writer.

I would prefer the default behavior of the server to be that the
origin has to match exactly, but that the app can override it, or when
the app is registered with the server it gives a list of acceptable
Origins.

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

---

From: Zhong Yu <[email-masked]>
Date: Mon, 22 Nov 2010 12:46:53 -0600

On Mon, Nov 22, 2010 at 10:38 AM, Simon Pieters <[email-masked]> wrote:
> If the server has a hardcoded Sec-WebSocket-Origin value, I have no problem
> with relying on the client checking that it matches what it sent.

In that case, how hard is it to match the single hardcoded Origin with
the single Origin the client sent? Why do we even give the server a
choice here?

> My problem
> is with servers just echoing the Origin and the app writer has no idea that
> it allows connections from anywhere.
>
Sure. But the policy of "Origin=Host" probably will work for most
deployments, therefore it's not a bad choice for default. Given that
it is safe.

> The "path" feature for cookies do not help anything with security, since the
> same-origin-policy allows you to open an iframe within the same origin and
> eat all the cookies.

That's interesting. Can you give me a link?

> That is by design, so that people don't fall into the cookie "path" trap and
> think they're safe when they're not.
>
>
>> The app can add its

---

From: Zhong Yu <[email-masked]>
Date: Mon, 22 Nov 2010 12:58:15 -0600

On Mon, Nov 22, 2010 at 10:58 AM, John Tamplin <[email-masked]> wrote:
> origin has to match exactly,
> but that the app can override it, or when

It's common that an application is deployed to different hosts at
different times: developer's PC, test server, beta server, production
server... The set of acceptable Origins are not fixed; rather it can
be better described as { Origin="Host in request" }

Anyways, the list of allowed Origin is not the concern of WS spec. I
wish the spec could be more serious about the matter and mandate the
server to match Origin against its list.

- Zhong Yu

---

From: "Simon Pieters" <[email-masked]>
Date: Mon, 22 Nov 2010 20:16:30 +0100

> origin has to match exactly,

Match what?

-- 
Simon Pieters
Opera Software

---

From: "Simon Pieters" <[email-masked]>
Date: Mon, 22 Nov 2010 20:58:32 +0100

On Mon, 22 Nov 2010 19:46:53 +0100, Zhong Yu <[email-masked]> wrote:

>> problem

I don't know, I assumed it is allowed because it would be simpler to  
implement in some situations (you don't need to check the origin the  
client sent)... Does it cause a problem in practice?

> deployments, therefore it's not a bad choice for default. Given that

Yeah, I agree that it is better than allowing connections from anywhere by  
default (could default protocol to 'http:' and maybe port to 80). I  
haven't given it much thought about whether it's always safe.

> That's interesting. Can you give me a link?

http://www.webappsec.org/lists/websecurity/archive/2006-03/msg00000.html

(via  
http://lcamtuf.blogspot.com/2010/10/http-cookies-or-how-not-to-design.html  
)

-- 
Simon Pieters
Opera Software

---

From: Sylvain Hellegouarch <[email-masked]>
Date: Mon, 22 Nov 2010 22:44:21 +0100

On Mon, Nov 22, 2010 at 5:58 PM, John Tamplin <[email-masked]> wrote:

> to
That's definitely how I'd implement it as well. The case that's left is when
the app doesn't provide any Origin, what should the server do? Default to
Origin=Host? Or should the request be rejected (I don' t quite see the point
of that mind you). It's the end, it's similar to the Sec-WebSocket-Protocol
header which is left up to the app writer to decide how to react and either
case.

-- 
- Sylvain
http://www.defuze.org
http://twitter.com/lawouach