CVE-2026-39987
Python vulnerability analysis and mitigation

Overview

CVE-2026-39987 is a pre-authentication remote code execution (RCE) vulnerability in marimo, an open-source reactive Python notebook platform. The terminal WebSocket endpoint /terminal/ws completely lacks authentication validation, allowing any unauthenticated attacker to obtain a full interactive PTY shell and execute arbitrary system commands. It affects marimo versions up to and including 0.20.4 and was disclosed on April 8, 2026, with a fix released in version 0.23.0. The vulnerability carries a CVSS v3.1 base score of 9.8 (Critical) and a CVSS v4.0 score of 9.3 (Critical) (GitHub Advisory, CISA KEV).

Technical details

The root cause is CWE-306 (Missing Authentication for Critical Function). In marimo/_server/api/endpoints/terminal.py, the /terminal/ws WebSocket endpoint only checks the running mode (SessionMode.EDIT) and platform support before calling websocket.accept() and spawning a PTY shell via pty.fork() — it never calls validate_auth(). By contrast, the /ws endpoint correctly uses WebSocketConnectionValidator.validate_auth() before accepting connections. Marimo's AuthenticationMiddleware (Starlette-based) marks unauthenticated connections as UnauthenticatedUser but does not actively reject WebSocket connections; actual enforcement depends on endpoint-level checks that /terminal/ws entirely omits. The fix (PR #9098, commit c24d480) adds a validate_auth() call gated on app_state.enable_auth, closing the connection with WebSocketCodes.UNAUTHORIZED if authentication fails (GitHub Advisory, GitHub PR).

Impact

An unauthenticated remote attacker can establish a single WebSocket connection to /terminal/ws and receive a full interactive PTY shell running with the privileges of the marimo process — typically root in default Docker deployments. This grants complete confidentiality, integrity, and availability impact: attackers can read sensitive files (.env, credentials, SSH keys, database connection strings), modify or destroy data, and use the compromised instance as a pivot point for lateral movement into connected cloud accounts, databases, and third-party APIs. Real-world exploitation confirmed credential theft (AWS access keys, API secrets) in under 3 minutes, and subsequent campaigns weaponized the flaw to deploy NKAbuse malware and blockchain-based backdoors via Hugging Face (Sysdig TRT, BleepingComputer).

Exploitability

This vulnerability is actively exploited in the wild and was added to CISA's Known Exploited Vulnerabilities (KEV) catalog on April 23, 2026, with a remediation due date of May 7, 2026 (CISA KEV). The Sysdig Threat Research Team observed the first exploitation attempt just 9 hours and 41 minutes after advisory publication — with no public PoC available at the time — and a complete credential theft operation was completed in under 3 minutes (Sysdig TRT). Multiple public PoC exploit scripts are now available, including a Python exploit at https://github.com/0xBlackash/CVE-2026-39987 and additional PoCs at https://github.com/h3raklez/CVE-2026-39987 and https://github.com/M3PH1569/CVE-2026-39987-POC. Malware families NKAbuse and KAgent have been confirmed to weaponize this vulnerability. The EPSS score is approximately 0.032 (3.2%). A Nuclei detection template (javascript/cves/2026/CVE-2026-39987.yaml) is also available. Threat actors subsequently used LLM agents for autonomous post-exploitation, pivoting from the initial RCE to internal databases in four steps (Sysdig TRT).

Exploitation steps

  1. Reconnaissance: Identify internet-facing marimo instances (default port 2718) using Shodan, Censys, or mass scanning tools. Target instances running marimo ≤ 0.20.4 in edit mode (marimo edit --host 0.0.0.0).
  2. Validate vulnerability: Connect to ws://TARGET:2718/terminal/ws using any WebSocket client (e.g., Python websocket-client library) without providing any authentication token or credentials.
  3. Confirm code execution: Send a structured PoC validation sequence to confirm RCE:
    echo '---POC-START---'
    id
    echo '---POC-END---'
    A response of uid=0(root) gid=0(root) groups=0(root) confirms full root shell access.
  4. Manual reconnaissance: Explore the filesystem interactively — run pwd, whoami, ls, ip addr to enumerate the environment and identify high-value files.
  5. Credential harvesting: Target sensitive files directly:
    cat .env
    cat docker-compose.yml
    ls ~/.ssh
    cat ~/.ssh/id_rsa
    Extract AWS keys, API tokens, database credentials, and SSH private keys.
  6. Lateral movement / persistence: Use harvested credentials to pivot to cloud accounts (AWS, GCP), internal databases, or deploy malware (e.g., NKAbuse, KAgent) downloaded from trusted platforms like Hugging Face to establish persistence (Sysdig TRT, GitHub Advisory).

Indicators of compromise

  • Network: Inbound WebSocket upgrade requests to /terminal/ws from unexpected or external IP addresses (legitimate use should be internal/authenticated only); outbound connections from the marimo host to unknown IPs or Hugging Face model repositories post-exploitation; known attacker IP 49.207.56.74 (India) observed in initial exploitation wave.
  • Logs: Web server/access logs showing GET /terminal/ws with HTTP 101 Switching Protocols from unauthenticated clients (no access_token parameter); repeated WebSocket connections from the same IP in short succession; commands such as id, whoami, cat .env, ls ~/.ssh appearing in terminal session logs.
  • File System: Unexpected access or exfiltration of .env, docker-compose.yml, or files in ~/.ssh; new files or binaries dropped in /tmp, /app, or world-writable directories; NKAbuse or KAgent malware artifacts present on disk.
  • Process: Unexpected child processes spawned by the marimo Python process (e.g., /bin/bash, sh, cat, curl, wget); pty.fork() spawning shells not initiated by authenticated users; unusual history command execution suggesting attacker checking for prior activity.
  • Behavioral: Rapid sequential reads of credential files (.env, SSH keys) within seconds of WebSocket connection establishment; echo '---POC-START---' / echo '---POC-END---' marker strings in terminal output logs (Sysdig TRT).

Mitigation and workarounds

Primary remediation: Upgrade marimo to version 0.23.0 or later immediately, which adds validate_auth() enforcement to the /terminal/ws endpoint (GitHub Advisory, CISA KEV). Workarounds if immediate patching is not possible:

  • Restrict network access to marimo instances (port 2718) to trusted internal networks only using firewall rules or security groups.
  • Place marimo behind a reverse proxy with authentication (e.g., nginx with HTTP Basic Auth or OAuth) to add an external authentication layer.
  • Disable or block the /terminal/ws endpoint at the network or proxy level if terminal functionality is not required.
  • Audit all .env files, cloud credentials (AWS, GCP, Azure), API keys, database passwords, and SSH keys on any marimo instance that has been publicly accessible, and rotate them as a precaution.
  • Monitor WebSocket connections to /terminal/ws for anomalous activity using runtime security tools (e.g., Falco with the available detection rules).

Community reactions

The marimo maintainer (mscolnick) acknowledged the vulnerability immediately upon disclosure and merged the fix (PR #9098) on April 8, 2026, the same day the advisory was published (GitHub PR). Sysdig's Threat Research Team published a detailed exploitation timeline report noting the sub-10-hour exploitation window and described it as evidence that threat actors are monitoring advisory feeds broadly and potentially using AI to accelerate exploit development (Sysdig TRT). SecurityWeek, BleepingComputer, The Hacker News, SC World, CSO Online, and Heise all covered the story, with BleepingComputer specifically reporting on the NKAbuse malware deployment campaign (BleepingComputer). The Belgium Centre for Cybersecurity (CCB) issued a warning advisory. Security researchers on Mastodon, Bluesky, and LinkedIn widely shared the Sysdig report, and the case was cited in subsequent research on LLM-agent-driven post-exploitation as a landmark example of AI-assisted cyberattacks (Sysdig TRT).

Additional resources


SourceThis report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-59177HIGH8.8
  • Python logoPython
  • esphome-device-builder
NoYesSep 09, 2026
CVE-2026-88005MEDIUM6.5
  • Python logoPython
  • open-webui
NoYesSep 10, 2026
CVE-2026-88002MEDIUM6.5
  • Python logoPython
  • open-webui
NoYesSep 09, 2026
CVE-2026-88000MEDIUM6.5
  • Python logoPython
  • cpe:2.3:a:openwebui:open_webui
NoYesSep 09, 2026
CVE-2026-88001MEDIUM5
  • Python logoPython
  • open-webui
NoYesSep 09, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management