CVE-2026-39987: Marimo Python Notebook Exposes Pre-Auth RCE — CISA Issues Emergency Patch Deadline
A critical CVSS 9.3 vulnerability in Marimo Python notebook versions ≤ 0.20.4 lets any attacker execute arbitrary code without credentials via an unauthenticated WebSocket endpoint. CISA added it to the Known Exploited Vulnerabilities catalog with an April 11 federal patch deadline.
Patch now: pip install --upgrade "marimo>=0.23.0"
CVE-2026-39987 is a pre-authentication remote code execution vulnerability in Marimo, the reactive Python notebook used widely by data scientists, ML engineers, and researchers. CVSS score: 9.3 (Critical, CVSS v4.0). Affected: all Marimo versions ≤ 0.20.4. Fixed in: 0.23.0. The Sysdig Threat Research Team observed the first in-the-wild exploit 9 hours and 41 minutes after public disclosure on April 10. CISA added it to the Known Exploited Vulnerabilities catalog with an April 11, 2026 remediation deadline for all federal agencies.
The Root Cause
The vulnerability lives in Marimo’s /terminal/ws WebSocket endpoint. Every other sensitive endpoint in Marimo properly calls validate_auth() before proceeding. This one skips it entirely.
The only checks performed before accepting a WebSocket connection are: (1) is the server in edit mode, and (2) does the host OS support PTY. Both are true in virtually all deployed configurations. After those two checks pass, Marimo calls websocket.accept() followed immediately by pty.fork(), handing the attacker a full interactive terminal session.
No credentials. No phishing. No session tokens. A single WebSocket connection.
What Attackers Take
The PTY shell runs as whatever user launched the Marimo server — often root in Docker deployments, frequently a developer’s local account with full access to their environment. Average credential exfiltration time observed in the wild: under 3 minutes. What gets stolen:
.envfiles (API keys, database passwords, service credentials)- AWS, GCP, and Azure access credentials stored locally
- SSH private keys
- Database connection strings
- Internal HTTP service URLs and tokens
If Marimo is running in a CI/CD pipeline, shared Jupyter-style environment, or cloud-hosted data platform, the blast radius extends well beyond the individual notebook.
Scale of Exposure
Marimo has approximately 19,600 GitHub stars and growing adoption in ML engineering and data science workflows. Endor Labs scanned 186 publicly reachable Marimo instances and found 16% — roughly 30 servers — still accepting unauthenticated /terminal/ws connections as of their scan window. That is a conservative floor; the vast majority of Marimo deployments are not publicly indexed.
Fix and Mitigations
Upgrade to 0.23.0 immediately:
pip install --upgrade "marimo>=0.23.0"
The patch adds proper authentication validation to the /terminal/ws endpoint before any WebSocket handshake.
If you cannot upgrade immediately:
- Restrict network access to Marimo’s port (default 2718) via firewall rules or VPN
- Never expose Marimo directly to the public internet
- Audit server logs for unexpected WebSocket connections to
/terminal/ws
Any Marimo instance that ran version ≤ 0.20.4 while network-accessible should be treated as fully compromised. Rotate all credentials stored in environment variables or accessible from the server, including cloud provider credentials, database passwords, and SSH keys.
Related reading
- Cybersecurity CVE-2026-42945 (CVSS 9.2): NGINX Rift Heap Overflow Exploited in the Wild — Unauthenticated RCE PoC Now Public
- Cybersecurity CVE-2026-48172 (CVSS 10.0): LiteSpeed cPanel Plugin Actively Exploited — Any User Can Run Scripts as Root
- Cybersecurity Microsoft Exchange Zero-Day CVE-2026-42897 Actively Exploited — No Full Patch, Automatic Mitigation Only