Skip to content

Commit

Permalink
Escape invalid host when displayed in html
Browse files Browse the repository at this point in the history
Use html.escape

Use web.HTTPError to safely return errors to browser
  • Loading branch information
manics committed Jun 9, 2024
1 parent f9ee190 commit ea1c272
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
16 changes: 7 additions & 9 deletions jupyter_server_proxy/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,11 @@ async def proxy(self, host, port, proxied_path):
'''

if not self._check_host_allowlist(host):
self.set_status(403)
self.write("Host '{host}' is not allowed. "
"See https://jupyter-server-proxy.readthedocs.io/en/latest/arbitrary-ports-hosts.html for info.".format(host=host))
return
raise web.HTTPError(
403,
f"Host '{host}' is not allowed. "
"See https://jupyter-server-proxy.readthedocs.io/en/latest/arbitrary-ports-hosts.html for info.",
)

# Remove hop-by-hop headers that don't necessarily apply to the request we are making
# to the backend. See https://github.com/jupyterhub/jupyter-server-proxy/pull/328
Expand Down Expand Up @@ -360,9 +361,7 @@ async def proxy(self, host, port, proxied_path):
# Ref: https://www.tornadoweb.org/en/stable/httpclient.html#tornado.httpclient.AsyncHTTPClient.fetch
if err.code == 599:
self._record_activity()
self.set_status(599)
self.write(str(err))
return
raise web.HTTPError(599, str(err))
else:
raise

Expand All @@ -371,8 +370,7 @@ async def proxy(self, host, port, proxied_path):

# For all non http errors...
if response.error and type(response.error) is not httpclient.HTTPError:
self.set_status(500)
self.write(str(response.error))
raise web.HTTPError(500, str(response.error))
else:
# Represent the original response as a RewritableResponse object.
original_response = RewritableResponse(orig_response=response)
Expand Down
9 changes: 9 additions & 0 deletions tests/test_proxies.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,15 @@ def test_server_proxy_host_absolute():
assert 'X-Forwarded-Context' not in s
assert 'X-Proxycontextpath' not in s


@pytest.mark.parametrize("absolute", ["", "/absolute"])
def test_server_proxy_host_invalid(absolute: str) -> None:
r = request_get(PORT, f"/proxy{absolute}/<invalid>:54321/", TOKEN)
assert r.code == 403
s = r.read().decode("ascii")
assert "Host &#39;&lt;invalid&gt;&#39; is not allowed." in s


def test_server_proxy_port_non_service_rewrite_response():
"""Test that 'hello' is replaced by 'foo'."""
r = request_get(PORT, '/proxy/54321/hello', TOKEN)
Expand Down

0 comments on commit ea1c272

Please sign in to comment.