Six contournements de permissions sur Mistral Vibe

Six vulnérabilités publiées le même jour sur l’agent de code de Mistral, toutes sur la même couche d’autorisation. La commande que l’agent inspecte pour décider n’est pas celle que le shell exécute.

TLP:CLEAR   PAP:CLEAR   Diffusion libre, exploitation sans restriction.
Publication
11 septembre 2026
Objet
Mistral Vibe, six CVE
Marquage
TLP:CLEAR, PAP:CLEAR
Confiance
Élevée
Sources
9

Les faits

Le 11 septembre 2026, HiddenLayer publie en tant que CNA (1) six CVE (2) visant Mistral Vibe, l’agent de code en ligne de commande de Mistral. Quatre portent un score CVSS (3) 4.0 de 10,0, une de 9,3, une de 9,2. Les six sont attribuées au même chercheur, Esteban Tonglet, et visent le même composant : le module qui décide si une commande shell peut s’exécuter sans demander l’accord de l’utilisateur.

Mistral Vibe est distribué sous licence Apache 2.0, installé depuis PyPI par le script d’installation de l’éditeur, par uv ou par pip. Il s’exécute sur le poste du développeur, avec les droits de son compte, et dispose d’un outil d’exécution de commandes shell dont une partie des invocations est approuvée automatiquement.

Ce qu’il faut retenir

Aucune de ces six vulnérabilités ne relève du modèle de langage. Ce sont des défauts de code ordinaire dans la couche d’autorisation qui entoure le modèle : analyse de chaînes de caractères, listes maintenues à la main, normalisation de chemins.

Un même défaut, six chemins

Le mécanisme commun tient en une phrase. Vibe reconstruit une représentation de la commande à partir de l’arbre syntaxique produit par tree-sitter-bash, puis prend sa décision d’autorisation sur cette représentation. Le shell, lui, exécute la chaîne d’origine. Chaque fois que la représentation perd un élément que le shell conserve, la décision porte sur autre chose que ce qui va s’exécuter.

Cinq des six défauts sont de cette nature. Le sixième vient d’un écart entre deux listes internes. Les catégories CWE (4) retenues diffèrent, l’effet est le même : une commande passe sans que l’utilisateur soit consulté.

CVEEffetÉlément perdu ou non contrôléCVSS 4.0CWEIntroduit en
CVE-2026-87983Lecture arbitraireGuillemets conservés dans le chemin, qui cesse d’être vu comme absolu9,2CWE-222.6.0
CVE-2026-87984Écriture arbitraireCible de redirection shell non extraite9,3CWE-221.3.4
CVE-2026-87985Exécution de codeArgument en quoting ANSI-C non collecté, le prédicat -exec de find disparaît10,0CWE-1842.9.0
CVE-2026-87986Exécution de codeSyntaxe que l’analyseur ne sait pas lire, placée sous un nœud d’erreur10,0CWE-2281.3.4
CVE-2026-87987Exécution de codeAffectations de variables d’environnement retirées avant le contrôle10,0CWE-152.6.0
CVE-2026-87988Lecture et écriture arbitrairesTrente et une commandes auto-approuvées absentes de la liste soumise au contrôle de chemin10,0CWE-7322.15.0

Deux illustrations

Pour la CVE-2026-87983, la commande cat "/etc/bashrc" suffit. Le contrôle de périmètre reçoit le jeton avec ses guillemets. Le premier caractère n’étant pas une barre oblique, le chemin n’est pas considéré comme absolu, il est résolu relativement au répertoire courant et paraît donc rester dans l’espace de travail. Bash retire ensuite les guillemets et cat lit le fichier réel. La même commande sans guillemets déclenche bien la demande d’accord.

Pour la CVE-2026-87987, l’attaquant place des affectations de variables d’environnement devant une commande autorisée : GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=diff.external GIT_CONFIG_VALUE_0='...' git diff. Les affectations sont retirées de la représentation utilisée pour la décision, il ne reste que git diff, qui figure dans l’allowlist, c’est à dire la liste des commandes autorisées sans demande d’accord. Bash lance ensuite Git avec l’environnement complet, Git charge le programme externe de comparaison et l’exécute.

Point de vigilance

Le classement d’une commande en lecture seule ne garantit même pas l’absence d’écriture. Dans la liste concernée par la CVE-2026-87988, sort avec son option de sortie, uniq avec son second argument positionnel et less avec son option de sauvegarde savent produire un fichier. La catégorie décrit l’intention d’usage, pas la capacité réelle du binaire.

C’est le point qui dépasse ce produit. Une allowlist ne décrit pas ce qu’un programme peut faire, elle décrit ce que son auteur croit qu’il fait. Dès que deux listes coexistent, l’une pour autoriser et l’autre pour contrôler, l’écart entre les deux devient la surface d’attaque.

Une accumulation sur huit mois

Les versions d’introduction déclarées par le CNA ne désignent pas une régression ponctuelle. Rapportées aux dates de publication de ces versions sur PyPI, elles couvrent huit mois de développement.

  • Version 1.3.4, publiée le 8 janvier 2026 : CVE-2026-87984 et CVE-2026-87986
  • Version 2.6.0, publiée le 23 mars 2026 : CVE-2026-87983 et CVE-2026-87987
  • Version 2.9.0, publiée le 28 avril 2026 : CVE-2026-87985
  • Version 2.15.0, publiée le 12 juin 2026 : CVE-2026-87988

Deux de ces défauts sont donc restés exploitables pendant huit mois. La dernière version publiée sur PyPI à la date de rédaction est la 2.25.1 du 9 septembre 2026, antérieure de deux jours aux avis. Aucune version corrigée n’est annoncée, ni par l’éditeur, ni dans les avis eux-mêmes.

Le produit vérifie chaque jour la présence d’une version plus récente sur PyPI et propose la mise à jour au lancement suivant. Ce mécanisme accélérera le déploiement du correctif quand il sortira, mais il ne remplace pas le recensement : il ne dit pas à l’exploitant combien de postes portent l’outil.

Qualification des sources

Les avis émanent du CNA lui-même et renvoient vers des lignes précises du dépôt public de l’éditeur. Le niveau de preuve est élevé, avec une réserve sur la notation.

ÉlémentStatutCommentaire
Mécanismes et lignes de code concernéescorroboréSix avis HiddenLayer, avec renvois vers le code source public
Scores et catégories CWEcorroboréValeurs concordantes entre les avis de l’éditeur et les fiches CVEFeed
Versions d’introductionsource uniqueDéclarées par le CNA, non recoupées. Leurs dates de publication sont vérifiées sur PyPI
Absence de version corrigéecorroboréAucune publication PyPI postérieure au 9 septembre 2026, aucun correctif mentionné dans les avis
Vecteur réseau retenu dans le scoresource uniqueVoir la réserve ci-dessous
Exploitation observéeécartéAucun signalement à la date de rédaction
Reprises par des agrégateurs secondairesécartéIdentifiants CVE non concordants avec les avis d’origine
Réserve sur la notation

Les six vecteurs retiennent AV:N, donc une exploitation par le réseau, sur un outil qui s’exécute sur le poste du développeur. Cette lecture tient si l’attaquant est le contenu ingéré par l’agent : un dépôt cloné, une page consultée, un ticket lu. Deux des six avis retiennent explicitement l’injection indirecte de prompt comme voie d’exploitation, ce qui rend la lecture cohérente. Un score de 10,0 obtenu par ce chemin ne se compare pas pour autant à un 10,0 sur un service exposé.

Évaluation

Facilité d’exploitation
Une syntaxe shell ordinaire suffit dans chaque cas. Aucune technique particulière.
Élevé
Impact sur le poste
Lecture, écriture et exécution avec les droits du compte qui fait tourner l’agent.
Élevé
Exposition réelle
Dépend du parc. Outil récent, installé à l’initiative du développeur, diffusion en entreprise limitée.
Modéré
Probabilité d’exploitation de masse
Cible individuelle, aucun service exposé, aucun code d’exploitation publié.
Faible
Note de méthode

Analyse construite sur les six avis du CNA, les fiches CVEFeed correspondantes, la documentation du produit et l’historique des versions publié sur PyPI. Le code source n’a pas été relu ligne à ligne et aucune reproduction n’a été tentée. Les appréciations d’exposition et de probabilité relèvent du jugement, pas de la mesure.

Ce qu’il faut faire

Si Mistral Vibe est présent sur le parc

  • Recenser les installations. L’agent s’installe à l’initiative du développeur et n’apparaît pas dans l’inventaire logiciel habituel. Le binaire s’appelle vibe, la configuration réside dans ~/.vibe.
  • Écarter les profils qui approuvent automatiquement. Les six contournements portent tous sur la décision d’auto-approbation. Le profil ask, qui demande l’accord pour toute exécution d’outil, retire son objet à cette logique. Les options --auto-approve et --yolo la désactivent entièrement et doivent être proscrites.
  • Interposer un contrôle externe. Le mécanisme de hooks du produit permet de déclarer un hook pre_tool qui reçoit les arguments de l’outil avant la demande d’accord et peut refuser l’exécution. Ce contrôle voit la commande complète, contrairement à la couche interne.
  • Cloisonner par le système. Conteneur, utilisateur dédié ou machine virtuelle, sans accès au répertoire personnel ni aux clés SSH (5) de l’utilisateur.
  • Retirer du poste les secrets en clair que le processus peut atteindre : fichiers d’identifiants, jetons d’API (6), clés privées non chiffrées.
  • Suivre la publication d’une version corrigée et l’appliquer dès sa sortie.

Ce que le cas dit des agents de code

Le montage est le même chez tous les éditeurs. Un modèle propose des commandes, une couche d’autorisation décide lesquelles passent sans demander. Cette couche est du code ordinaire, faite d’analyseurs de chaînes de caractères et de listes maintenues à la main. Six contournements publiés le même jour sur un seul produit donnent la mesure de sa solidité.

La conséquence pratique est simple. Le périmètre de confiance d’un agent de code n’est pas la liste de ses commandes autorisées, c’est l’ensemble de ce que son processus peut atteindre. Le cloisonnement doit venir du système, par un conteneur, un utilisateur dédié ou un montage restreint, pas de la logique interne de l’outil.

Reste la question du vecteur. Dans deux des six avis, l’attaquant n’est pas l’utilisateur mais le contenu que l’agent lit : un dépôt cloné, un ticket, une page web. La couche d’autorisation est le seul endroit où cette entrée non fiable est arbitrée avant de devenir une commande. C’est précisément l’endroit où six défauts viennent d’être publiés.

Lexique

  1. CNA (1) : CVE Numbering Authority, entité habilitée à attribuer des identifiants CVE dans son périmètre.
  2. CVE (2) : Common Vulnerabilities and Exposures, identifiant public unique d’une vulnérabilité.
  3. CVSS (3) : Common Vulnerability Scoring System, cadre de notation standardisé de la gravité d’une vulnérabilité.
  4. CWE (4) : Common Weakness Enumeration, classification des types de faiblesses logicielles.
  5. SSH (5) : Secure Shell, protocole d’accès distant chiffré, dont les clés privées résident sur le poste.
  6. API (6) : Application Programming Interface, interface d’accès programmatique à un service, dont les jetons d’authentification résident souvent sur le poste.

Sources

  1. HiddenLayer, avis de sécurité SAI relatif à la CVE-2026-87983, 11 septembre 2026. hiddenlayer.com
  2. HiddenLayer, avis de sécurité SAI relatif à la CVE-2026-87984, 11 septembre 2026. hiddenlayer.com
  3. HiddenLayer, avis de sécurité SAI relatif à la CVE-2026-87985, 11 septembre 2026. hiddenlayer.com
  4. HiddenLayer, avis de sécurité SAI relatif à la CVE-2026-87986, 11 septembre 2026. hiddenlayer.com
  5. HiddenLayer, avis de sécurité SAI relatif à la CVE-2026-87987, 11 septembre 2026. hiddenlayer.com
  6. HiddenLayer, avis de sécurité SAI relatif à la CVE-2026-87988, 11 septembre 2026. hiddenlayer.com
  7. CVEFeed, fiches CVE-2026-87983 à CVE-2026-87988, consultées le 11 septembre 2026. cvefeed.io
  8. PyPI, projet mistral-vibe, historique des versions, consulté le 11 septembre 2026. pypi.org
  9. Mistral AI, documentation de Mistral Vibe, profils d’agents, hooks et mise à jour, consultée le 11 septembre 2026. github.com

Marquage TLP:CLEAR, PAP:CLEAR. Diffusion libre, exploitation sans restriction.

Les analyses présentées ici n’engagent que leur auteur et reposent sur les sources publiques listées ci-dessus.