Skip to content

Commit 968c56c

Browse files
authored
Redact tokens, etc. in url parameters from request logs (jupyter-server#1212)
replaces `?token=abc123` with `?token=[secret]` in logs
1 parent ee6c660 commit 968c56c

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

jupyter_server/log.py

+29-2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,39 @@
66
# the file LICENSE, distributed as part of this software.
77
# -----------------------------------------------------------------------------
88
import json
9+
from urllib.parse import urlparse, urlunparse
910

1011
from tornado.log import access_log
1112

1213
from .auth import User
1314
from .prometheus.log_functions import prometheus_log_method
1415

16+
# url params to be scrubbed if seen
17+
# any url param that *contains* one of these
18+
# will be scrubbed from logs
19+
_SCRUB_PARAM_KEYS = {"token", "auth", "key", "code", "state", "xsrf"}
20+
21+
22+
def _scrub_uri(uri: str) -> str:
23+
"""scrub auth info from uri"""
24+
parsed = urlparse(uri)
25+
if parsed.query:
26+
# check for potentially sensitive url params
27+
# use manual list + split rather than parsing
28+
# to minimally perturb original
29+
parts = parsed.query.split("&")
30+
changed = False
31+
for i, s in enumerate(parts):
32+
key, sep, value = s.partition("=")
33+
for substring in _SCRUB_PARAM_KEYS:
34+
if substring in key:
35+
parts[i] = f"{key}{sep}[secret]"
36+
changed = True
37+
if changed:
38+
parsed = parsed._replace(query="&".join(parts))
39+
return urlunparse(parsed)
40+
return uri
41+
1542

1643
def log_request(handler):
1744
"""log a bit more information about each request than tornado's default
@@ -43,7 +70,7 @@ def log_request(handler):
4370
"status": status,
4471
"method": request.method,
4572
"ip": request.remote_ip,
46-
"uri": request.uri,
73+
"uri": _scrub_uri(request.uri),
4774
"request_time": request_time,
4875
}
4976
# log username
@@ -59,7 +86,7 @@ def log_request(handler):
5986
msg = "{status} {method} {uri} ({username}@{ip}) {request_time:.2f}ms"
6087
if status >= 400: # noqa[PLR2004]
6188
# log bad referers
62-
ns["referer"] = request.headers.get("Referer", "None")
89+
ns["referer"] = _scrub_uri(request.headers.get("Referer", "None"))
6390
msg = msg + " referer={referer}"
6491
if status >= 500 and status != 502: # noqa[PLR2004]
6592
# Log a subset of the headers if it caused an error.

0 commit comments

Comments
 (0)