TL;DR

Mercury, the framework that turns a Jupyter notebook into a web app or dashboard the way Streamlit turns a script into one, runs a JupyterLab server with anonymous access by default and relies on a blocklist of endpoints. A missing comma in that blocklist let /api/terminals through, so anyone who could reach a Mercury app could open an interactive OS shell as the server user (CVE-2026-111057, CVSS 3.1 10.0, fixed 3.2.4), and the blocklist never covered /api/kernels, so anonymous clients could create a kernel and send it Python to run (CVE-2026-111058, CVSS 3.1 9.8, fixed 3.2.6). The vendor published both advisories in August 2026; the CVE ids were assigned and the advisories reached the GitHub Advisory Database on 2026-10-19. The newest release is 3.2.11. Upgrade, and put authentication in front of any Mercury app that faces a network.

What happened

Mercury (mljar/mercury, PyPI mercury) serves notebooks as parameterised web apps. Underneath it is a JupyterLab server, and Mercury's security model for anonymous users is a list of blocked URL patterns in mercury_app/block_handler.py rather than per-request authentication.

CVE-2026-111057 / GHSA-f8c7-rwf9-fmgm. Published by the maintainer (pplonski) on 2026-08-21; reporter szotgan. Affected >= 3.0.0, <= 3.2.3; patched 3.2.4 (PyPI 2026-08-21). The /lab and /api/terminals regular-expression literals in BLOCKED_PATTERNS were concatenated by a missing comma, so requests to /api/terminals bypassed the anonymous blocklist and reached Jupyter Server's terminal API. The advisory's words: "any unauthenticated attacker can spawn a full, interactive OS-level shell" on the host, read any file the Mercury process can, modify or delete files including notebooks served to other users, and use the shell as a foothold. CVSS 3.1 10.0 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H), CWE-185 and CWE-284. The fix adds the comma.

CVE-2026-111058 / GHSA-rv4m-xm3f-3ccq. Published 2026-08-31; finder CyberKareem (Abdullah Kareem). Affected 3.2.5 and earlier; patched 3.2.6 (PyPI 2026-08-28). Default tokenless deployments let anonymous clients create Jupyter kernels and send execute_request messages containing arbitrary Python, because the blocklist does not cover /api/kernels and the websocket wrapper tracked idle activity without authorising executable messages. The advisory states this is distinct from the terminal bug and that the 3.2.4 fix does not cover kernels. CVSS 3.1 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H). The advisory's recommended fix is real per-request authentication by default, or restricting the kernel channel so anonymous clients cannot send execution requests outside Mercury's controlled flow.

Both CVE records are GitHub-CNA, published 2026-10-19, and the database rows carry the same date; the vendor pages are dated 2026-08-21 and 2026-08-31. This file is dated by the vendor. PyPI, read 2026-10-20: 3.2.4 on 2026-08-21, 3.2.5 on 08-27, 3.2.6 on 08-28, newest 3.2.11.

Why it is here: Mercury is in the Streamlit class, the layer a data scientist or a coding agent reaches for to put a notebook on a URL, and it shipped with the same default this corpus keeps filing for agent platforms: a code-execution service with anonymous access and a denylist as the only gate.

Am I affected?

  • pip show mercury on the host. Affected: 3.0.0 through 3.2.3 for the terminal bug; anything before 3.2.6 for the kernel bug.
  • A Mercury app is exposed if anything that can reach its port can reach it without first authenticating elsewhere. The vendor lists VPN, reverse-proxy authentication and firewall rules as the only things that limited exposure before the fixes.
  • The CVE records and advisories name no exploitation in the wild. The 10.0 and 9.8 scores are the CNA's; the mechanism, an unauthenticated shell and an unauthenticated kernel, supports them.

If you are affected

  1. pip install -U "mercury>=3.2.6" and restart; the newest is 3.2.11.
  2. If the app was reachable from an untrusted network while on an affected version, treat the host as compromised: review the Jupyter server log for terminal and kernel creation from unexpected clients, and rotate every credential the server process could read, per rotating cloud credentials and if your webapp was compromised.
  3. Put an authenticating reverse proxy in front of Mercury regardless of version. The upstream model is still a blocklist in front of an anonymous Jupyter server.

Prevention

  • Agent sandboxing: any service that executes code on request belongs behind an authenticating boundary and inside a container with no credentials it does not need.
  • Credential hygiene.

Sources