Live › vulnerability › CVE-2026-111058
Go to dashboardMercury (the mljar Python package) runs a JupyterLab server that is anonymous by default and blocks only a few endpoints, leaving /api/kernels reachable. An unauthenticated network client can start a kernel, send an execute_request over websocket, and run arbitrary Python as the server process user.
Summary written from the sources below. Check the originals before acting.
First seen by InfraStack 2026-10-23 19:11 UTC, 3h before NVD. All times on this page are UTC.
| Product | Ecosystem | Affected | Fixed in |
|---|---|---|---|
| mercury | pypi | <= 3.2.5 | 3.2.6 |
pip show mercury versions 3.2.5 and below are affected3.2.6 or later, per the advisory's fixed versionEach row is the first time that source carried this signal. The analyst’s rows are its own findings.
Mercury runs a JupyterLab server with anonymous access by default (mercury_app/__main__.py sets --IdentityProvider.token='' when no --token/MERCURY_TOKEN is given; when tokenless it also sets --ServerApp.disable_check_xsrf=True). It relies on a blocklist (mercury_app/block_handler.py BLOCKED_PATTERNS: /lab, /api/terminals, /api/shutdown, /files) to keep anonymous users off dangerous Jupyter endpoints.
/api/kernels is NOT in the blocklist (and cannot be — Mercury needs kernels to run notebooks), and patch_kernel_websocket_handler() (mercury_app/idle_timeout.py) only tracks the idle-timeout: it wraps on_message to call self.application._timeout_manager.touch() and then invokes the original handler with no filtering of execute_request. So any unauthenticated network client can:
POST /api/kernels {"name":"python3"} -> 201, returns kernel id
open websocket /api/kernels/<id>/channels
send an execute_request with arbitrary code -> arbitrary Python execution = RCE
GHSA-f8c7 was "Unauthenticated RCE via /api/terminals" — a missing-comma blocklist bypass. Its fix (add the comma so /api/terminals is blocked) does NOT address /api/kernels, which remains exploitable. The blocklist approach is fundamentally unable to cover kernels, so this is not a variant that another blocklist entry fixes.
On mercury 3.2.4 — the release that fixed GHSA-f8c7 — with the default (tokenless) config, as an unauthenticated client: POST /api/terminals returns 403 (the f8c7 fix is present), but POST /api/kernels returns 201; opening the kernel websocket and sending an execute_request executed attacker-supplied Python (ran whoami as the server process user and wrote a marker file /tmp/PWNED_MERCURY_RCE). Full unauthenticated remote code execution. Deterministic PoC (client script + notebook) included.
Unauthenticated, network-reachable arbitrary code execution as the Mercury server process user on every default deployment — complete compromise of the host/container and any data/secrets it can reach.
The blocklist cannot secure an anonymous kernel-backed server. Require real per-request authentication (a token or password) by default, or restrict the kernel message channel so anonymous websocket clients cannot issue execute_request outside Mercury's own controlled execution flow.
OSV.dev CLEAN(0) for mercury and mljar-mercury; the repo's only advisory (GHSA-f8c7-rwf9-fmgm) covers /api/terminals only (description does not mention kernels); no issue/PR describes the /api/kernels RCE (#219/#134/#262 are "add auth" feature requests that merely confirm anonymous-by-default). Sink independently confirmed on current HEAD (blocklist omits /api/kernels; token='' default; patch_kernel_websocket_handler does no execute filtering).
Finder: Abdullah Kareem (GitHub: CyberKareem).
This page as .md · .json · in your agent: get_signal("CVE-2026-111058")
GitHub Advisory Database, CC-BY 4.0 · NVD data is provided by NIST and is public domain. Posts quoted belong to their authors.