Aller au contenu
Kreomnis.Vigie
CVE-2026-39987Critique9.3 KEV

Marimo : la RCE pré-auth qui a vu un agent LLM piloter seul toute la post-exploitation

Publiée le 16/06/2026// Kreomnis
CVSS 4.0
9.3
EPSS : probabilité d'exploitation
-
Source : FIRST.org, modèle EPSS v3
Produits/versions affectés
  • marimo ≤ 0.20.4
CISA KEV : exploitation observée

Cette vulnérabilité est inscrite au catalogue des vulnérabilités activement exploitées de la CISA. Traitement prioritaire recommandé.

Le contexte

marimo est un notebook Python réactif, de plus en plus présent dans les chaînes de data science et d'outillage IA. Avant la version 0.23.0, il embarque une RCE pré-authentifiée : l'endpoint WebSocket /terminal/ws accepte des connexions sans aucune authentification et ouvre un PTY (pseudo-terminal) complet à quiconque s'y connecte. Toutes les versions ≤ 0.20.4 sont concernées. CVSS v4.0 9.3.

La faille est sortie du lot à deux reprises. D'abord par sa vitesse d'exploitation : Sysdig a observé la première tentative in-the-wild moins de 10 heures après la publication de l'avis. Ensuite, et c'est l'angle qui en fait le sujet de l'année, par ce qui s'est passé le 10 mai 2026.

Ce jour-là, l'équipe Threat Research de Sysdig a capté la première intrusion confirmée dans la nature où un agent LLM a composé et exécuté seul une chaîne d'attaque à quatre pivots, sans opérateur humain pilotant chaque étape. CISA avait ajouté la CVE à son catalogue KEV le 23 avril 2026 (échéance fédérale au 7 mai).

La mécanique

La cause racine est une authentification manquante sur une fonction critique (CWE-306). Contrairement aux autres endpoints WebSocket de marimo (par exemple /ws, qui appelle correctement validate_auth()), /terminal/ws ne vérifie que le mode d'exécution et le support de la plateforme avant d'accepter la connexion.

Conséquence directe :

  • un attaquant non authentifié ouvre une connexion WebSocket sur /terminal/ws,
  • il obtient un shell PTY interactif avec les privilèges du processus marimo,
  • à partir de là : lecture de fichiers sensibles, vol de secrets, installation de portes dérobées, pivot réseau.

Ce qui rend l'incident historique

La post-exploitation du 10 mai n'a pas été menée par un humain au clavier, mais par un agent LLM autonome. Sysdig a relevé quatre indicateurs caractéristiques d'un pilotage par modèle de langage, dont le fait que l'attaquant a improvisé un dump de base sans aucune connaissance préalable du schéma.

La chaîne, longue d'un peu plus d'une heure (~68 minutes), s'est déroulée ainsi :

  1. RCE initiale sur un notebook marimo exposé sur Internet via CVE-2026-39987.
  2. Extraction de deux identifiants cloud depuis l'hôte compromis.
  3. Rejeu de ces identifiants à travers un pool d'egress éclaté pour récupérer une clé privée SSH dans AWS Secrets Manager.
  4. Huit courtes sessions SSH contre un bastion en aval, qui ont exfiltré le schéma et l'intégralité d'une base PostgreSQL interne en 113 secondes (moins de deux minutes).

PostgreSQL, justement : c'est le moteur de stockage qui sous-tend une grande partie des plateformes de veille et de data intelligence. Une base interne vidée en moins de deux minutes par un agent qui n'en connaissait pas le schéma, c'est le scénario que tout RSSI doit désormais intégrer à sa modélisation de menace.

Versions impactées

| Produit | Version | Statut | | --- | --- | --- | | marimo | ≤ 0.20.4 | Vulnérable | | marimo | 0.23.0 et ultérieures | Corrigée |

Comment patcher

# Vérifier la version installée
python -m marimo --version
# ou
pip show marimo
  1. Mettre à jour vers marimo ≥ 0.23.0 sans délai :
pip install --upgrade "marimo>=0.23.0"
  1. Ne jamais exposer un notebook marimo directement sur Internet. Placer l'instance derrière une authentification forte (reverse proxy + SSO/mTLS) et restreindre l'accès réseau.

  2. Mitigation immédiate si le patch n'est pas applicable : bloquer l'accès à /terminal/ws au niveau du reverse proxy et désactiver le mode terminal quand il n'est pas indispensable.

  3. Chasse à la compromission (la CVE est dans KEV, l'exploitation est réelle) :

    • surveiller les connexions WebSocket vers /terminal/ws provenant de sources inattendues,
    • corréler avec des accès anormaux à AWS Secrets Manager et des rafales de sessions SSH courtes vers un bastion,
    • tracer les pg_dump / requêtes de schéma information_schema non planifiés côté PostgreSQL.

PoC

Des scripts de détection et des preuves de concept publiques (notamment des NSE Nmap et des clients de connexion au terminal) circulent sur GitHub depuis la divulgation. L'exploitation est triviale une fois l'endpoint joignable : la connexion au WebSocket suffit à obtenir le shell. Lier vers la source originale, ne jamais ré-héberger le code.

Ce qu'il faut retenir

Une RCE pré-auth d'apparence classique, mais le premier cas documenté d'une post-exploitation entièrement pilotée par un agent LLM : reconnaissance, pivots, choix des cibles et dump de base improvisés par la machine.

Pour les RSSI, SOC et DevSecOps :

  • Patch en urgence vers 0.23.0 et sortie immédiate de toute exposition Internet : la CVE est dans KEV.

  • Réduisez la valeur d'un pivot : un hôte compromis ne doit pas donner accès à des identifiants cloud en clair, ni un secret manager déverrouiller une clé SSH menant à un bastion menant à PostgreSQL. Segmentez, rotez, cloisonnez les secrets.

  • Adaptez la détection à la vitesse machine : 68 minutes de la RCE au dump complet, 113 secondes pour la base. Les playbooks pensés pour un opérateur humain au clavier sont déjà en retard. Misez sur la détection comportementale temps réel (egress anormal, accès secret manager, rafales SSH).

  • Kreomnis

Références

#marimo#notebook-python#rce#pre-auth#agent-llm