
Proof-of-concept d'exploit pour CVE-2026-39987, une RCE de pré-authentification dans le point de terminaison WebSocket /terminal/ws de Marimo qui permet d'obtenir un shell interactif sans identifiants.
CVSS 4.0 : 9.3 (Critique) · AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H
Affecte : marimo <= 0.20.4 · Corrigé : 0.23.0 · CWE-306 (Authentification manquante)
Avis : GHSA-2679-6mx9-h9xc · Correctif : marimo-team/marimo@c24d480
Le point de terminaison WebSocket /terminal/ws (marimo/_server/api/endpoints/terminal.py)
vérifie uniquement le mode de session (EDIT) et la prise en charge de la plateforme avant d'accepter la
connexion et d'appeler pty.fork(). Il ne porte ni décorateur @requires(...)
ni appel à validate_auth().
Comparaison mesurée en 0.20.4 :
@requires(...) sur 18 points de terminaison./ws (notebook) -> 2 appels à .validate_auth()terminal.py -> 0 @requires, 0 validate_auth. <-- la faille.Le middleware AuthBackend protège HTTP et le websocket /ws, mais
/terminal/ws accepte la connexion sans cookie ni jeton et lance un
shell PTY avec les privilèges du processus marimo.
marimo edit ...), qui est le mode par défaut de l'éditeur.pty (Linux/macOS ; Windows et Pyodide ne sont pas affectés).Un attaquant capable d'atteindre un serveur marimo edit sur le réseau (courant dans
les déploiements distants / conteneurisés, souvent exécutés en root) obtient un shell
interactif sans s'authentifier : vol d'identifiants (cat .env), mouvement latéral,
déploiement de logiciels malveillants. Exploité dans la nature < 10 h après la divulgation ; ajouté au
catalogue KEV de la CISA le 2026-04-23.
pip install "marimo==0.20.4" websockets
marimo edit demo.py --headless --port 2718 --token --token-password SECRET
python exploit.py ws://127.0.0.1:2718 "id; cat /etc/passwd"
exploit.py n'envoie ni jeton, ni cookie, ni en-tête Authorization. Il envoie la
commande sous forme de texte brut + "\r" (Entrée), exactement comme un utilisateur la saisirait dans le terminal.
/ws -> 403 (l'authentification FONCTIONNE)./terminal/ws SANS jeton -> ACCEPTÉ. Exécuté sur le serveur :
uid=1000() gid=1000() ...
Linux ...
et a écrit /tmp/cve_2026_39987_proof.txt -> RCE confirmé.Mettre à niveau vers marimo >= 0.23.0. Atténuation temporaire : ne pas exposer marimo edit
à des réseaux non fiables ; placer l'éditeur derrière un proxy authentifié ; l'exécuter
sans privilèges / dans un conteneur sans secrets.
À des fins de tests de sécurité autorisés et d'usage éducatif uniquement. Ne l'exécutez que contre des systèmes que vous possédez ou pour lesquels vous disposez d'une autorisation explicite de test.