GoogleChromeLabs / pywebsocket3

BSD 3-Clause "New" or "Revised" License
44 stars 32 forks source link

pywebsocket permits connections from any origin in the default configuration #8

Closed ricea closed 3 years ago

ricea commented 4 years ago

Migrated from https://github.com/google/pywebsocket/issues/135:

What steps will reproduce the problem?
1. Start pywebsocket in the default configuration
2. Connect a websocket from some other origin (eg. 
http://www.websockets.org/echo.html

What is the expected output? 

Connection is refused due to bad origin.

What do you see instead?

Connection is allowed.

Please provide any additional information below.

Although it is not intended as a production server, pywebsocket should still 
embody best practices. Best practice would be to follow the principle of "least 
privilege", ie. closed by default.

Proposal:

1. Add a --default-allowed-origins option to standalone.py. If this is not 
specified, the default value is http://<host>:<port> (or https://<host>:<port> 
if running in secure mode).
_This Will Break Some Existing Users_

To restore the behaviour of previous versions, they can add
--default-allowed-origins=*

To achieve maximum security, they can add
--default-allowed-origins=""
(ie. no origins at all permitted by default, every handler will need to 
explicitly enable the origins it needs)

For the Blink layout tests
--default-allowed-origins=http://127.0.0.1:*
would be appropriate.

The general form is a list of wildcards, eg.
--default-allowed-origins=http://*.example.com:*,https://*.example.com:*
Default ports should do the sensible thing, ie. if the browser sends
Origin: http://www.example.com
this should be considered a match for http://www.example.com:* or 
http://www.example.com:8*

2. Add a new allowed_origins member to the |request| parameter to 
web_socket_do_extra_handshake(). By default, this contains the value of the 
--default-allowed-origins parameter, converted to a python list. 
web_socket_do_extra_handshake() can change the value to change the accepted 
origins, eg.

    request.allowed_origins = ['*']

to permit the handler to be used from any origin. The handler can also use this 
to do custom origin checking, eg.

    request.allowed_origins = ['*']
    if request.ws_origin in huge_set_of_origins:
        return
    raise ValueError('Unacceptable origin: %r' % request.ws_origin)

examples/origin_check_wsh.py should be changed to

def web_socket_do_extra_handshake(request):
    request.allowed_origins = ['http://example.com']

Original issue reported on code.google.com by ri...@google.com on 10 Dec 2014 at 2:35

ricea commented 4 years ago

I don't like that pywebsocket's default behaviour is bad, but we're unlikely to change it now.

ricea commented 3 years ago

Since pywebsocket is only used for testing, it's not worth fixing this.