GHSA-c3mw-737p-c7g2: High severity pip/jupyter_server vulnerability
Summary
When a request returns a 500, jupyterserver/log.py logs a small JSON block of request headers.
The Referer header was copied into it as-is, so a token in the Referer URL ended up in the logs in plain text.
Impact
Anyone who can read the server logs can pick tokens out of these 500 entries. Tokens end up in the Referer during normal token-based login and launch flows.
Affected: all versions before 2.21.0.
PoC
Any malformed request that returns a 500 works:
bash curl -i -X POST \ -H 'Content-Type: application/json' \ -H 'Referer: http://127.0.0.1:8899/tree?token=REFERTOKEN' \ --data '{"name":123}' \ 'http://127.0.0.1:8899/api/kernels?token=VALIDTOKEN'
The log shows the token twice, once raw and once redacted:
"Referer": "http://127.0.0.1:8899/tree?token=REFERTOKEN", [E ... ServerApp] 500 POST /api/kernels?token=[secret] (...) referer=http://127.0.0.1:8899/tree?token=[secret]
Patches
Fixed in 2.21.0 by 5251352. Header values are now scrubbed before the block is logged. Upgrade to 2.21.0 or later.
Workarounds
Limit who can read the server logs. If you can, avoid flows that put the token in the URL.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/jupyter_serverto a version that resolves this vulnerability.Fixed in 2.21.0 - Upgrade
Upgrade
Jupyter Serverto a version that resolves this vulnerability.Fixed in 2.21.0Patch 5251352 - Configuration
After upgrading to 2.21.0, header values (including Referer) are scrubbed before being logged for 500 responses in jupyter_server/log.py.
Jupyter Server (logging) Reference header logging behavior = scrubbed - Compensating control
Limit who can read the server logs, since tokens extracted from 500 entries could be used if logs are accessible.
- Compensating control
Avoid request flows that put the token in the URL (e.g., avoid token query parameters in URLs such as /api/kernels?token=...).
Event History
Frequently Asked Questions
Who can exploit the exposed tokens?
Anyone who can read Jupyter Server logs containing relevant 500-response entries can recover tokens from unredacted Referer header values. The attacker does not need to directly trigger the malformed request if another user or process has already generated the log entry.
What conditions cause a token to be written to the logs?
A request must result in a 500 response and include a Referer URL containing a token. Tokens can appear in Referer headers during normal token-based login and launch flows; any malformed request that produces a 500 can trigger the logging behavior.
Are default token-based deployments affected?
Yes. The affected behavior applies to all Jupyter Server versions before 2.21.0, and normal token-based login and launch flows can place tokens in Referer URLs.
What should be done if an immediate upgrade is not possible?
Restrict access to Jupyter Server logs to reduce the chance that logged tokens can be recovered. Where possible, avoid workflows that put authentication tokens in URLs.
How can I check whether tokens may already have been exposed?
Review server logs for 500-response entries containing the JSON request-header block, especially unredacted Referer values with token parameters. Treat any token visible in those entries as potentially exposed.