CVE-2026-39987 Overview
CVE-2026-39987 is a critical Pre-Authentication Remote Code Execution (RCE) vulnerability affecting marimo, a reactive Python notebook application. The vulnerability exists in the terminal WebSocket endpoint /terminal/ws, which lacks proper authentication validation, allowing unauthenticated attackers to obtain a full PTY (pseudo-terminal) shell and execute arbitrary system commands on the host system.
Unlike other WebSocket endpoints in the marimo application (such as /ws) that correctly implement authentication by calling validate_auth(), the /terminal/ws endpoint only verifies the running mode and platform support before accepting connections. This oversight completely bypasses authentication verification, creating a direct path for remote attackers to gain shell access without any credentials.
Critical Impact
Unauthenticated attackers can execute arbitrary system commands with the privileges of the marimo process, potentially leading to complete system compromise, data exfiltration, lateral movement, or deployment of additional malware.
Affected Products
- marimo versions prior to 0.23.0
Discovery Timeline
- 2026-04-09 - CVE-2026-39987 published to NVD
- 2026-04-09 - Last updated in NVD database
Technical Details for CVE-2026-39987
Vulnerability Analysis
This vulnerability is classified under CWE-306 (Missing Authentication for Critical Function). The flaw resides in the terminal WebSocket endpoint implementation within marimo's server architecture. When a WebSocket connection is established to /terminal/ws, the server fails to invoke the validate_auth() function that other sensitive endpoints utilize for authentication verification.
The impact of this vulnerability is severe due to the nature of what the terminal endpoint provides—a full PTY shell. An attacker who successfully exploits this vulnerability gains the ability to execute arbitrary commands with the same privileges as the marimo process. This could include reading sensitive files, modifying data, installing backdoors, pivoting to other systems on the network, or disrupting service operations.
Root Cause
The root cause is a missing authentication check in the terminal WebSocket endpoint handler. While the endpoint performs checks for running mode and platform compatibility (whether the system supports terminal functionality and isn't running in Pyodide or restricted Windows modes), it completely omits the critical step of validating user authentication. This represents an inconsistency in the security implementation across different WebSocket endpoints in the marimo codebase.
Attack Vector
The attack vector is network-based and requires no authentication or user interaction. An attacker can exploit this vulnerability by:
- Identifying a marimo instance exposed to the network
- Establishing a WebSocket connection directly to the /terminal/ws endpoint
- Bypassing all authentication since the endpoint doesn't validate credentials
- Obtaining a full PTY shell session
- Executing arbitrary system commands with the privileges of the marimo process
The security patch adds the missing authentication by importing and calling validate_auth from marimo._server.api.auth:
from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState
from marimo import _loggers
+from marimo._server.api.auth import validate_auth
from marimo._server.api.deps import AppState
+from marimo._server.codes import WebSocketCodes
from marimo._server.router import APIRouter
from marimo._session.model import SessionMode
from marimo._utils.platform import is_pyodide, is_windows
Source: GitHub Commit Changes
Detection Methods for CVE-2026-39987
Indicators of Compromise
- Unexpected WebSocket connections to the /terminal/ws endpoint from external or unauthorized IP addresses
- Unusual command execution patterns or processes spawned by the marimo process
- Network traffic showing WebSocket upgrade requests to terminal endpoints without prior authenticated session establishment
- Log entries indicating terminal sessions initiated without corresponding authentication events
Detection Strategies
- Monitor WebSocket connection logs for /terminal/ws endpoint access patterns and correlate with authentication events
- Implement network intrusion detection rules to alert on WebSocket connections to marimo terminal endpoints from untrusted sources
- Deploy endpoint detection to identify suspicious child processes spawned by Python processes running marimo
- Review access logs for patterns indicating reconnaissance or exploitation attempts against WebSocket endpoints
Monitoring Recommendations
- Enable verbose logging for marimo server to capture all WebSocket connection attempts
- Configure SIEM alerts for connections to marimo instances from external networks
- Implement baseline monitoring for normal terminal usage patterns to detect anomalous activity
- Monitor for process creation events linked to the marimo application that deviate from expected behavior
How to Mitigate CVE-2026-39987
Immediate Actions Required
- Upgrade marimo to version 0.23.0 or later immediately
- Restrict network access to marimo instances using firewall rules, limiting exposure to trusted networks only
- Audit systems running marimo for signs of compromise, particularly checking for unauthorized processes or modified files
- If upgrade is not immediately possible, disable or block access to the /terminal/ws endpoint at the network level
Patch Information
The vulnerability has been fixed in marimo version 0.23.0. The fix properly implements authentication for the terminal WebSocket endpoint by adding the validate_auth() call that was missing from the original implementation. Organizations should update to version 0.23.0 or later to remediate this vulnerability.
For more details, see the GitHub Security Advisory and the Pull Request #9098.
Workarounds
- Block external access to marimo instances using network-level controls (firewall rules, security groups)
- Deploy a reverse proxy with authentication in front of marimo to add an additional authentication layer
- Disable terminal functionality entirely if not required by removing or blocking access to the /terminal/ws route
- Implement network segmentation to ensure marimo instances are only accessible from trusted internal networks
# Example: Block external access to marimo terminal endpoint using iptables
# Allow only localhost connections to the marimo port (adjust port as needed)
iptables -A INPUT -p tcp --dport 2718 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 2718 -j DROP
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


