Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

accept implicit port 80 on whitelist #3513

Merged
merged 2 commits into from Jan 4, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 13 additions & 1 deletion bokeh/server/tests/test_tornado.py
Expand Up @@ -17,4 +17,16 @@ def test__whitelist_replaces_prepare_only_once():
tornado._whitelist(h)
new_prepare = h.prepare
tornado._whitelist(h)
assert h.prepare == new_prepare
assert h.prepare == new_prepare

def test_check_whitelist_rejects_port_mismatch():
assert False == tornado.check_whitelist("foo:100", ["foo:101", "foo:102"])

def test_check_whitelist_rejects_name_mismatch():
assert False == tornado.check_whitelist("foo:100", ["bar:100", "baz:100"])

def test_check_whitelist_accepts_name_port_match():
assert True == tornado.check_whitelist("foo:100", ["foo:100", "baz:100"])

def test_check_whitelist_accepts_implicit_port_80():
assert True == tornado.check_whitelist("foo", ["foo:80"])
19 changes: 18 additions & 1 deletion bokeh/server/tornado.py
Expand Up @@ -25,12 +25,29 @@
from .application_context import ApplicationContext
from .views.static_handler import StaticHandler

# factored out to be easier to test
def check_whitelist(request_host, whitelist):
''' Check a given request host against a whitelist.

'''
if request_host not in whitelist:

# see if the request came with no port, assume port 80 in that case
if len(request_host.split(':')) == 1:
host = request_host + ":80"
return host in whitelist
else:
return False

return True


def _whitelist(handler_class):
if hasattr(handler_class.prepare, 'patched'):
return
old_prepare = handler_class.prepare
def _prepare(self, *args, **kw):
if self.request.host not in self.application._hosts:
if not check_whitelist(self.request.host, self.application._hosts):
log.info("Rejected connection from host '%s' because it is not in the --host whitelist" % self.request.host)
raise HTTPError(403)
return old_prepare(self, *args, **kw)
Expand Down
6 changes: 4 additions & 2 deletions bokeh/server/views/ws.py
Expand Up @@ -42,12 +42,14 @@ def initialize(self, application_context, bokeh_websocket_path):
pass

def check_origin(self, origin):
from ..tornado import check_whitelist
parsed_origin = urlparse(origin)
origin_host = parsed_origin.netloc.lower()

allowed = self.application.websocket_origins
allowed_hosts = self.application.websocket_origins

if origin_host in allowed:
allowed = check_whitelist(origin_host, allowed_hosts)
if allowed:
return True
else:
log.error("Refusing websocket connection from Origin '%s'; use --allow-websocket-origin=%s to permit this; currently we allow origins %r", origin, origin_host, allowed)
Expand Down