Background
Marimo is a modern reactive Python notebook environment designed as a successor to Jupyter. Unlike traditional notebooks where cell execution is manual and stateful, Marimo re-executes dependent cells automatically when upstream values change, bringing a reactive programming model to interactive data science. Marimo notebooks are shareable as interactive web applications and can be run as scripts, making them attractive for both development workflows and internal tooling deployments. The project is developed and maintained by CoreWeave engineers and has gained significant adoption in the AI/ML community.
The security model for notebook environments is inherently complex. By design, notebooks execute arbitrary Python code — that is their purpose. Security controls therefore focus on ensuring that only authorised users can submit code for execution. Marimo implements authentication for most of its WebSocket-based communication channels, using session tokens to validate that only users with a valid browser session can interact with notebooks.
However, CVE-2026-39987 reveals a critical inconsistency in this authentication model: the /terminal/ws endpoint, which provides a full interactive PTY (pseudo-terminal) shell backed by the host OS, was excluded from authentication checks. This omission is particularly severe because a PTY shell is a more powerful primitive than notebook code execution — it provides direct, interactive access to the underlying system without any notebook-level sandboxing.
Technical Mechanism
Marimo’s embedded terminal feature spawns an OS-level PTY process (typically /bin/bash or the system’s default shell) and bridges it to the browser via WebSocket. The /terminal/ws WebSocket endpoint handles the bidirectional data stream between the browser terminal UI and the PTY process.
In versions before 0.23.0, the endpoint handler for /terminal/ws omits the authentication middleware that all other WebSocket endpoints apply. The authentication check validates the presence of a valid session cookie established through the browser login flow. Because /terminal/ws skips this check, any WebSocket client — including unauthenticated HTTP clients — can connect to the endpoint and interact directly with the PTY session.
The exploit is trivial to execute:
import websocket
ws = websocket.WebSocket()
ws.connect("ws://target-marimo-server:2718/terminal/ws")
# Send a command to the shell
ws.send("id && hostname && cat /etc/passwd\n")
print(ws.recv())
Upon connection, the attacker receives a fully interactive shell as the user running the Marimo process. Because Marimo is typically run by data scientists or developers on workstations or shared compute nodes, this user often has broad filesystem access and may have cloud provider credentials (AWS, GCP, Azure) configured in environment variables or credential files.
The vulnerability is classified CWE-306 (Missing Authentication for Critical Function) — a straightforward case where a high-privilege function was simply not wired to the authentication subsystem. The CVSS 4.0 score of 9.3 reflects the severity under the newer scoring model.
Real-World Exploitation Evidence
CISA’s addition to the KEV catalogue followed evidence of automated scanning targeting exposed Marimo instances on default port 2718. The attack surface is non-trivial: many data science teams run Marimo on cloud compute instances — including GPU nodes — with port 2718 directly exposed to the internet or bound to 0.0.0.0 on shared networks without a reverse proxy, under the assumption that notebook environments are for internal use.
Confirmed exploitation scenarios include:
- Cryptomining operations targeting organisations running Marimo on high-compute GPU infrastructure, with mining payloads deployed within minutes of initial access
- Exfiltration of cloud provider credentials from environment variables and
.aws/credentialsfiles accessible to the Marimo process, enabling subsequent lateral movement into cloud environments - Access to Hugging Face tokens and other ML API credentials stored in environment variables or notebook configuration files
- On shared multi-user compute nodes, exploitation of the shell access to read other users’ home directories and files accessible to the Marimo user’s group
The attack pattern is particularly efficient for adversaries because the Marimo process often has access to valuable AI/ML credentials and compute resources in a single hop.
Impact Assessment
- Full interactive shell as the Marimo process user — not limited to notebook-level Python execution
- Cloud credential theft: Data scientists typically have cloud API keys, Hugging Face tokens, and model API keys accessible to the Marimo process
- Filesystem access: Read and write access to all files accessible to the running user, including notebooks, datasets, model weights, and configuration files
- Network pivoting: GPU cloud nodes are often in VPCs with internal routing to databases, storage, and other compute — the shell enables further lateral movement
- Persistent backdoor installation: Attackers can add SSH keys, cron jobs, or systemd user services to maintain access after the Marimo session is terminated
- Supply chain risk: If Marimo notebooks are part of a CI/CD or model training pipeline, shell access enables injection of malicious code into downstream artifacts
Affected Versions
| Product | Affected Versions | Fixed Version |
|---|---|---|
| Marimo | All versions before 0.23.0 | 0.23.0 |
| Marimo | 0.1.0 – 0.22.x | Upgrade to 0.23.0 |
Remediation Steps
-
Upgrade Marimo: Install version 0.23.0 or later via pip:
pip install --upgrade marimo. This release adds authentication enforcement to the/terminal/wsendpoint, consistent with all other WebSocket endpoints. -
Restrict network exposure immediately: If upgrading is not immediately possible, bind Marimo to
127.0.0.1only (marimo run --host 127.0.0.1) and require SSH tunnelling for remote access. Do not expose port 2718 to untrusted networks. -
Disable the terminal feature: If the embedded terminal is not required, consider running Marimo with terminal functionality disabled until the patch can be applied (check release notes for the
--no-terminalflag introduced in 0.23.0). -
Rotate exposed credentials: Audit environment variables and credential files accessible to the Marimo process. If the instance was internet-accessible while running a vulnerable version, rotate all cloud provider credentials, API keys, and tokens.
-
Review access logs: Examine Marimo server logs and network flow data for WebSocket connections to
/terminal/wsfrom unexpected source IPs, particularly before the patch was applied. -
Implement a reverse proxy with authentication: For any internet-facing deployment, place Marimo behind a reverse proxy (nginx, Caddy, or a cloud load balancer) that enforces authentication before connections reach the Marimo process.
Detection Guidance
Indicators of exploitation to look for:
- WebSocket upgrade requests to
/terminal/wsfrom IP addresses not associated with known users or administrative hosts - Shell history (
~/.bash_history,~/.zsh_history) containing commands consistent with reconnaissance or persistence:id,whoami,env,cat ~/.aws/credentials,crontab -e,curl | bash - Unexpected outbound connections from the Marimo host to mining pool addresses or external infrastructure on non-standard ports
- New files created in the user’s home directory or
/tmpwith executable permissions outside of normal workflow times - Environment variable reads of cloud credential files via process monitoring (auditd
openatsyscall audit for.aws/credentials,.config/gcloud/, etc.) - Unexpected CPU or GPU utilisation spikes consistent with cryptomining workloads
Timeline
| Date | Event |
|---|---|
| 2026-03-28 | Vulnerability reported to Marimo security team |
| 2026-04-15 | Marimo 0.23.0 released with authentication fix for /terminal/ws |
| 2026-04-21 | Public security advisory published; CVE assigned |
| 2026-04-23 | CISA adds CVE-2026-39987 to the Known Exploited Vulnerabilities catalogue |
| 2026-05-07 | CISA mandatory remediation deadline for federal agencies |
| 2026-04-23 | This analysis published |