{"id":"GHSA-rv4m-xm3f-3ccq","summary":"Mercury: Unauthenticated Remote Code Execution via /api/kernels","details":"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.\n\n## The vulnerability\n`/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:\n\n```\nPOST /api/kernels {\"name\":\"python3\"}        -\u003e 201, returns kernel id\nopen websocket /api/kernels/\u003cid\u003e/channels\nsend an execute_request with arbitrary code -\u003e arbitrary Python execution = RCE\n```\n\n## Distinct from GHSA-f8c7-rwf9-fmgm (incomplete fix)\nGHSA-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.\n\n## Runtime-proven (on the patched version)\nOn **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.\n\n## Impact\nUnauthenticated, 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. \n\n## Fix\nThe 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.\n\n## Dedup (3-method)\nOSV.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).\n\nFinder: Abdullah Kareem (GitHub: CyberKareem).","aliases":["CVE-2026-111058"],"modified":"2026-10-19T17:00:04.132793757Z","published":"2026-10-19T16:49:08Z","database_specific":{"cwe_ids":["CWE-862"],"severity":"CRITICAL","github_reviewed":true,"github_reviewed_at":"2026-10-19T16:49:08Z","nvd_published_at":null},"references":[{"type":"WEB","url":"https://github.com/mljar/mercury/security/advisories/GHSA-rv4m-xm3f-3ccq"},{"type":"WEB","url":"https://github.com/mljar/mercury/commit/73a40ceb0becf057f495a5738ad7f5a5222a53e1"},{"type":"PACKAGE","url":"https://github.com/mljar/mercury"},{"type":"WEB","url":"https://github.com/mljar/mercury/releases/tag/3.2.6"}],"affected":[{"package":{"name":"mercury","ecosystem":"PyPI","purl":"pkg:pypi/mercury"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.2.6"}]}],"versions":["1.1.6","1.99.0","1.99.1","1.99.10","1.99.2","1.99.3","1.99.4","1.99.5","1.99.6","1.99.7","1.99.8","1.99.9","2.0.0","2.0.1","2.0.10","2.0.11","2.0.12","2.0.2","2.0.3","2.0.4","2.0.5","2.0.6","2.0.7","2.0.8","2.0.9","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.1.6","2.1.7","2.1.8","2.1.9","2.2.0","2.2.1","2.2.2","2.2.3","2.2.4","2.2.5","2.2.6","2.2.7","2.2.8","2.2.9","2.3.0","2.3.1","2.3.10","2.3.2","2.3.3","2.3.4","2.3.5","2.3.6","2.3.7","2.3.8","2.3.9","2.4.0","2.4.1","2.4.2","2.4.3","3.0.0","3.0.0a1","3.0.0a10","3.0.0a11","3.0.0a12","3.0.0a2","3.0.0a3","3.0.0a4","3.0.0a5","3.0.0a6","3.0.0a7","3.0.0a8","3.0.0a9","3.0.0b1","3.0.0b2","3.0.0b3","3.0.0b4","3.0.0b5","3.0.0b6","3.0.0rc1","3.0.1","3.0.2","3.1.0","3.1.1","3.1.2","3.1.4","3.1.5","3.2.0","3.2.1","3.2.2","3.2.3","3.2.4","3.2.5"],"database_specific":{"last_known_affected_version_range":"\u003c= 3.2.5","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-rv4m-xm3f-3ccq/GHSA-rv4m-xm3f-3ccq.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}]}