Table of Contents

CVE-2026-39987 is a CVSS 9.3 critical vulnerability in Marimo’s WebSocket terminal endpoint that allowed unauthenticated remote attackers to spawn an interactive shell on any reachable instance1. The flaw existed because /terminal/ws skipped the authentication check that other endpoints enforced, leaving every Marimo notebook server at or below version 0.20.4 exposed to pre-authentication remote code execution2.

The Vulnerability: How /terminal/ws Skipped Authentication

Marimo’s terminal feature exposes a WebSocket at /terminal/ws that provides a browser-based PTY shell. While the adjacent /ws endpoint called validate_auth() to enforce access controls, the terminal handler checked only whether the server was in edit mode and whether the platform supported PTY allocation — it never invoked the authentication routine2. The result was that any network-reachable Marimo instance running a vulnerable version would hand a root shell to anyone who opened the WebSocket, without a password or token.

The flaw was rated CVSS 9.3 critical by GitHub (the CNA) under the CVSS 4.0 vector AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N; NIST’s own NVD assessment had not yet been published at time of writing1. Versions through 0.20.4 are affected; the fix shipped in 0.23.0 on April 9, 20263.

Exploitation Timeline: 9 Hours, 41 Minutes, and a 3-Minute Credential Theft

Sysdig’s threat-research team ran a honeypot that captured the first post-disclosure exploitation attempt at 07

UTC on April 9, 2026 — exactly 9 hours and 41 minutes after the advisory was published at 21
UTC on April 84. The gap between public disclosure and first exploit was narrower than the 12-hour 31-minute window Sysdig had observed for LMDeploy’s CVE-2026-33626 earlier in the month5.

At 07

UTC, thirteen minutes after the initial shell, the attacker exfiltrated the honeypot’s .env file, completing credential theft in under three minutes4. Over the observation window, Sysdig logged 125 unique IP addresses performing reconnaissance against the terminal endpoint, but only one IP — 49.207.56.74, geolocated to India — conducted actual exploitation. That single actor ran four sessions spanning roughly 90 minutes4.

What the Attacker Actually Targeted

Once inside the honeypot, the attacker searched for .env files, AWS credentials, SSH keys, docker-compose.yml, and shell history4. The exfiltrated .env contained generic application secrets and AWS credentials; Sysdig’s published analysis does not list provider-specific AI keys such as OpenAI, Anthropic, or Google among the observed loot4.

The absence of observed AI keys in this incident does not eliminate the structural risk. AI notebooks are often configured with live API keys for hosted model providers as a working convenience, meaning a successful compromise of the notebook layer frequently yields access to the production AI stack downstream.

The AI Tooling Layer Pattern: Marimo, LMDeploy, and Shrinking Disclosure-to-Exploit Windows

Marimo’s 9-hour 41-minute window is not an isolated data point. It sits alongside LMDeploy’s 12-hour 31-minute exploitation timeline as evidence that attackers are prioritizing AI development infrastructure5. The common thread is not the specific language or framework but the concentration of credentials: inference endpoints, notebook servers, and model-serving layers all tend to accumulate the secrets that gate access to expensive GPU clusters and paid API accounts.

For security teams, the practical consequence is that the AI notebook layer has become a credential-aggregation chokepoint. A pre-auth RCE in a tool like Marimo does not merely compromise the host — it potentially compromises every API key, cloud credential, and model access token stored in the working environment.

What Teams Running Notebooks Should Do Now

Upgrade to Marimo 0.23.0 or later immediately3. Because the vulnerability is pre-authentication and trivial to exploit, any instance on a network segment that an attacker can reach should be treated as potentially compromised.

Beyond patching, rotate any credentials that were present on affected hosts. The attacker in Sysdig’s observation specifically hunted for .env files and AWS keys, so assume that any secret stored on the server is burned4.

Network placement matters. Marimo’s edit mode is designed for local development; if it must run on a remote host, put it behind a VPN or authenticate at the reverse-proxy layer rather than relying on the application’s own access controls alone. The fact that /terminal/ws bypassed validate_auth() is a reminder that WebSocket endpoints are easy to overlook during security reviews, and that notebooks, by design, keep their secrets close to the code.

Frequently Asked Questions

Does this affect Marimo instances shared in run or presentation mode?

No. The /terminal/ws endpoint only activates when Marimo runs in edit mode and the host platform supports PTY allocation. Deployments using run mode — the default for sharing notebooks as dashboards or reports — never expose the terminal WebSocket, so they were not vulnerable to this specific vector.

How do these sub-10-hour exploitation windows compare to typical enterprise patch cycles?

Most enterprises operate on 30-to-90-day patch cycles for non-critical infrastructure. Both Marimo (9h 41m) and LMDeploy (12h 31m) were exploited well before a scheduled patch window would have closed, meaning standard patch management is structurally inadequate for AI development tooling. Network segmentation and credential isolation become the primary controls, not patching alone.

What does the CVSS 9.3 score miss about the real blast radius?

The CVSS 4.0 vector rates all subsequent-system impacts as None (SC

/SI
/SA
), treating the compromise as confined to the Marimo host. In practice, notebooks routinely hold live AWS credentials, API keys, and model access tokens in .env files and runtime environments. The attacker’s 3-minute credential exfil demonstrates that the actual downstream impact extends well beyond the host — a gap the scoring framework doesn’t capture for credential-dense development tools.

What detection signals would have caught this exploit before credential exfiltration?

Real-time alerting on PTY sessions spawned via WebSocket connections, outbound-traffic baselining from notebook hosts, and file-access monitoring on .env and credential files would all have flagged the activity. The attacker completed exfiltration in under 3 minutes, so batch log review is too slow; the detection window demands inline or near-real-time alerts on the notebook host itself.

Footnotes

  1. NVD CVE-2026-39987 Detail 2

  2. GitHub Advisory GHSA-2679-6mx9-h9xc: Pre-Auth RCE via Terminal WebSocket Authentication Bypass 2

  3. Marimo GitHub Releases 2

  4. Marimo OSS Python Notebook RCE — From Disclosure to Exploitation in Under 10 Hours 2 3 4 5 6

  5. CVE-2026-33626 — How Attackers Exploited LMDeploy LLM Inference Engines in 12 Hours 2

Sources

  1. NVD CVE-2026-39987 Detailprimaryaccessed 2026-04-24
  2. GitHub Advisory GHSA-2679-6mx9-h9xc: Pre-Auth RCE via Terminal WebSocket Authentication Bypassvendoraccessed 2026-04-24
  3. Marimo GitHub Releasescommunityaccessed 2026-04-24
  4. Marimo OSS Python Notebook RCE — From Disclosure to Exploitation in Under 10 Hoursanalysisaccessed 2026-04-24
  5. CVE-2026-33626 — How Attackers Exploited LMDeploy LLM Inference Engines in 12 Hoursanalysisaccessed 2026-04-24

Enjoyed this article?

Stay updated with our latest insights on AI and technology.