{"id":"CVE-2026-111058","aliases":["EUVD-2026-104420","GHSA-rv4m-xm3f-3ccq"],"status":"published","title":"Mercury: Unauthenticated Remote Code Execution via /api/kernels","description":"Mercury is a Python framework for sharing Jupyter notebooks as web applications and dashboards. Prior to 3.2.6, default tokenless deployments allow anonymous clients to create Jupyter kernels and send execute_request messages containing arbitrary Python. The endpoint blocklist does not cover /api/kernels, and the websocket wrapper previously tracked idle activity without authorizing executable messages. This issue is fixed in version 3.2.6.","severity":{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-12","score":0.00523,"percentile":0.4488,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":true,"fix_available":true},"cwes":["CWE-862"],"published":"2026-10-19T16:06:22Z","modified":"2026-10-28T02:30:42Z","exploits":[{"source":"pocgithub","id":"ExDev994/CVE-2026-111058-CVE-2026-111057-mercury-rce","title":"ExDev994/CVE-2026-111058-CVE-2026-111057-mercury-rce","date":"2026-10-20","url":"https://github.com/ExDev994/CVE-2026-111058-CVE-2026-111057-mercury-rce"}],"fixes":[{"ecosystem":"PyPI","package":"mercury","fixed_in":["3.2.6"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"mercury","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"3.2.5"},{"fixed":"3.2.6"}]}]},{"source":"osv","ecosystem":"PyPI","package":"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"]}],"products":[{"vendor":"mljar","product":"mercury"}],"references":[{"url":"https://github.com/mljar/mercury/security/advisories/GHSA-rv4m-xm3f-3ccq","tags":["x_refsource_CONFIRM","advisory","web"]},{"url":"https://github.com/mljar/mercury/commit/73a40ceb0becf057f495a5738ad7f5a5222a53e1","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/mljar/mercury/releases/tag/3.2.6","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/advisories/GHSA-rv4m-xm3f-3ccq"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/111xxx/CVE-2026-111058.json","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-111058","tags":["advisory"]},{"url":"https://github.com/mljar/mercury","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-111058","title":"Mercury: Unauthenticated Remote Code Execution via /api/kernels","description":"Mercury is a Python framework for sharing Jupyter notebooks as web applications and dashboards. Prior to 3.2.6, default tokenless deployments allow anonymous clients to create Jupyter kernels and send execute_request messages containing arbitrary Python. The endpoint blocklist does not cover /api/kernels, and the websocket wrapper previously tracked idle activity without authorizing executable messages. This issue is fixed in version 3.2.6.","status":"published","published":"2026-10-19T16:06:22.646Z","modified":"2026-10-19T17:06:53.899Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"cna"}],"cwes":["CWE-862"],"updated_at":"2026-11-02T14:20:15.34316Z"}],"euvd":[{"id":"EUVD-2026-104420","description":"Mercury is a Python framework for sharing Jupyter notebooks as web applications and dashboards. Prior to 3.2.6, default tokenless deployments allow anonymous clients to create Jupyter kernels and send execute_request messages containing arbitrary Python. The endpoint blocklist does not cover /api/kernels, and the websocket wrapper previously tracked idle activity without authorizing executable messages. This issue is fixed in version 3.2.6.","status":"published","published":"2026-10-19T16:06:22Z","modified":"2026-10-19T17:06:53Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"updated_at":"2026-11-02T16:59:50.463489Z"}],"ghsa":[{"id":"GHSA-rv4m-xm3f-3ccq","title":"Mercury: Unauthenticated Remote Code Execution via /api/kernels","description":"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).","status":"published","published":"2026-10-19T16:49:08Z","modified":"2026-10-19T16:49:08Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"cwes":["CWE-862"],"updated_at":"2026-11-02T14:41:32.483482Z"}],"nvd":[{"id":"CVE-2026-111058","description":"Mercury is a Python framework for sharing Jupyter notebooks as web applications and dashboards. Prior to 3.2.6, default tokenless deployments allow anonymous clients to create Jupyter kernels and send execute_request messages containing arbitrary Python. The endpoint blocklist does not cover /api/kernels, and the websocket wrapper previously tracked idle activity without authorizing executable messages. This issue is fixed in version 3.2.6.","status":"published","published":"2026-10-19T16:17:03.957Z","modified":"2026-10-19T21:13:39.973Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical","assessor":"secondary"}],"cwes":["CWE-862"],"updated_at":"2026-11-02T14:13:00.83844Z"}],"osv":[{"id":"CVE-2026-111058","title":"Mercury: Unauthenticated Remote Code Execution via /api/kernels","description":"Mercury is a Python framework for sharing Jupyter notebooks as web applications and dashboards. Prior to 3.2.6, default tokenless deployments allow anonymous clients to create Jupyter kernels and send execute_request messages containing arbitrary Python. The endpoint blocklist does not cover /api/kernels, and the websocket wrapper previously tracked idle activity without authorizing executable messages. This issue is fixed in version 3.2.6.","status":"published","published":"2026-10-19T16:06:22.646Z","modified":"2026-10-28T02:30:42.994400363Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"cwes":["CWE-862"],"updated_at":"2026-11-02T15:44:55.61515Z"},{"id":"GHSA-rv4m-xm3f-3ccq","title":"Mercury: Unauthenticated Remote Code Execution via /api/kernels","description":"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).","status":"published","published":"2026-10-19T16:49:08Z","modified":"2026-10-19T17:00:04.132793757Z","cvss":[{"version":"3.1","score":9.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"critical"}],"cwes":["CWE-862"],"updated_at":"2026-11-02T15:46:56.281047Z"}]}}
