système : OPÉRATIONNEL
← retour à tous les hacks
AGENTS CRITICAL NEW

Quand l'agent exécute son propre code : le CodeAgent de PraisonAI transforme l'injection de prompt en RCE

Divulguée le 11 juillet 2026, une faille de sévérité maximale dans PraisonAI exécute du Python généré par le LLM sans contrôle d'AST, ni restriction d'imports, ni sandbox — un prompt bien conçu devient du code arbitraire sur l'hôte.

2026-07-14 // 7 min affects: praisonai, codeagent, llm-agents

De quoi s’agit-il ?

Le 11 juillet 2026, une faille d’exécution de code à distance de sévérité maximale a été publiée contre PraisonAI, un framework open source populaire d’orchestration multi-agents. La vulnérabilité se situe dans le composant CodeAgent, conçu pour laisser un LLM écrire du Python puis l’exécuter. Dans toutes les versions antérieures à la 1.6.78, ce code s’exécutait sans aucun garde-fou : pas d’inspection de l’arbre syntaxique, aucune restriction sur les modules importables, et aucune sandbox pour confiner le processus. Notée 10.0 (critique) sur l’échelle CVSS 4.0 et classée en injection de code (CWE-94), c’est le genre de découverte qui transforme un simple prompt en shell sur l’hôte.

C’est aussi un exemple d’école d’une classe de failles sur laquelle nous revenons régulièrement : dès qu’un framework d’agents peut exécuter ce que le modèle génère, l’injection de prompt cesse d’être un problème de contenu pour devenir un problème d’exécution de code. Il s’agit ici d’une lecture défensive d’un problème publiquement divulgué et déjà corrigé — pas d’un guide d’exploitation.

Comment ça marche

La conception de CodeAgent est simple, et c’est précisément là le problème. Une tâche est confiée à l’agent, le LLM produit un extrait de Python censé la résoudre, et le framework exécute cet extrait pour en obtenir le résultat. La partie dangereuse est l’étape d’exécution, dans la routine _execute_python().

Tâche / prompt  ──▶  Le LLM génère du Python  ──▶  _execute_python()  ──▶  s'exécute sur l'hôte
                     (l'attaquant peut orienter          │
                      ce contenu)                        └── pas de contrôle d'AST
                                                         └── pas de liste blanche d'imports
                                                         └── pas de sandbox / isolation

Comme la chaîne générée est transmise telle quelle à un interpréteur actif, tout ce que le modèle peut être amené à écrire, l’hôte l’exécutera — avec les privilèges du processus PraisonAI. Et l’attaquant n’a pas besoin d’accéder directement à l’interpréteur. L’orientation se fait un niveau au-dessus, au niveau du prompt : n’importe quel texte non fiable ingéré par l’agent (un document récupéré, un résultat d’outil, une page web, un message utilisateur) peut pousser le modèle à produire du Python qui lit des variables d’environnement, ouvre une connexion réseau ou touche au système de fichiers. La divulgation décrit l’impact concret comme l’exfiltration de tous les secrets d’environnement et l’exécution de commandes arbitraires sur l’hôte.

Le vecteur de sévérité raconte le reste : accessible par le réseau, faible complexité, aucun privilège ni interaction utilisateur requis (AV:N/AC:L/PR:N/UI:N), avec un impact élevé sur la confidentialité, l’intégrité et la disponibilité. Aucun proof-of-concept public n’accompagnait l’advisory, et la faille n’était pas signalée comme exploitée dans la nature au moment de la publication (EPSS d’environ 0,5 %). La date de réservation était le 9 juillet 2026 ; la publication a suivi le 11 juillet 2026.

Pourquoi c’est important

Le réflexe serait de ranger ceci dans « encore une RCE dans encore un framework ». Ce serait passer à côté de l’essentiel. Les composants de type CodeAgent — un LLM qui écrit du code et un runtime qui l’exécute — sont désormais une brique standard dans tout l’écosystème des agents, vendue comme la fonctionnalité qui permet aux agents de « faire du vrai travail ». Chacun de ces composants hérite de la même exposition structurelle : l’exécuteur fait confiance au modèle, et le modèle fait confiance à son entrée. Cassez l’entrée, et vous cassez l’hôte.

Deux propriétés rendent cela pire qu’un bug d’injection classique. D’abord, la surface d’attaque est sémantique, pas syntaxique. Il n’existe pas une seule chaîne malveillante à mettre en liste noire ; l’attaquant doit seulement amener le modèle à produire du Python dangereux mais valide, et il existe une infinité de façons de le formuler. Ensuite, les agents sont de plus en plus reliés à du contenu non fiable par conception — corpus de récupération, sorties d’outils, pages scrappées — de sorte que le « prompt » qui atteint le modèle est rarement saisi par un humain de confiance. C’est la condition de la triade létale (données privées, contenu non fiable, exécution de code/sortie réseau) réduite à un seul et même processus.

Pour quiconque fait tourner PraisonAI, l’enjeu pratique est immédiat : une instance auto-hébergée exposée au réseau, ou alimentée par des documents extérieurs à la frontière de confiance, doit être considérée comme exécutable à distance jusqu’à sa mise à jour. Pour tous les autres, c’est une invitation à auditer si un agent de votre stack exécute du code écrit par le modèle, et sous quel confinement.

Défenses

Le correctif de l’éditeur est le premier geste ; le reste est une architecture qui tient même lorsque la prochaine fonctionnalité de type CodeAgent sera livrée.

  1. Mettez à jour vers PraisonAI 1.6.78 ou une version ultérieure. C’est la remédiation documentée pour cette faille. Figez la version dans votre manifeste de dépendances et reconstruisez toute image de conteneur embarquant une version antérieure.
  2. N’exécutez jamais de code généré par le modèle sur l’hôte. Si un agent doit exécuter du code, faites-le dans une sandbox jetable, sans réseau — conteneur verrouillé, gVisor/microVM, ou service d’interpréteur dédié — avec racine en lecture seule, aucun secret monté et une sortie réseau en interdiction par défaut. Le rayon d’impact d’une injection de code se définit par l’endroit où le code s’exécute, pas par la façon dont il a été généré.
  3. Ne placez pas de secrets dans l’environnement d’exécution. Les variables d’environnement sont la première chose exfiltrée dans cette classe de bugs. Injectez les identifiants au dernier moment via un broker que la sandbox ne peut pas atteindre, pour qu’un interpréteur compromis n’ait rien à voler.
  4. Contraignez ce que l’interpréteur peut même exprimer. Là où vous contrôlez l’exécuteur, appliquez une liste blanche d’AST et d’imports avant toute exécution, et rejetez le code qui touche à os, subprocess, socket, à l’import dynamique ou à la réflexion. C’est une mitigation, pas un mur — à traiter comme défense en profondeur derrière la sandbox, pas à sa place.
  5. Traitez toute entrée non humaine comme hostile. Documents récupérés, réponses d’outils et pages scrappées sont contrôlables par l’attaquant. Étiquetez leur provenance et interdisez au contenu arrivant par ces canaux d’influencer une étape d’exécution de code. Journalisez le code exact que l’agent exécute et alertez sur les appels réseau ou système de fichiers.
  6. Inventoriez vos agents. Posez-vous, pour chaque framework d’agents déployé, la question : exécute-t-il du code écrit par le modèle, des commandes shell ou du SQL ? Si oui, où cette exécution a-t-elle lieu, que peut-elle atteindre, et quelle est son identité ? PraisonAI n’est pas un cas isolé — c’est le mode de défaillance récurrent de l’injection de prompt vers la RCE dans les frameworks d’agents.

Status

ÉlémentRéférenceDateNotes
CVE réservéeVulnCheck (CNA)2026-07-09Attribuée à la faille d’exécution de code du CodeAgent de PraisonAI
Advisory publiéeNVD / GitHub Security Advisory GHSA-2xv2-w8cq-5gxw2026-07-11Score de base CVSS 4.0 de 10.0, CWE-94
Versions affectéesAdvisory GitHubPraisonAI (praisonaiagents) avant 1.6.78
Version corrigéeAdvisory GitHub2026-071.6.78 et ultérieures
Exploitée dans la natureOffSeq / NVD2026-07-11Non observée à la publication ; EPSS ≈ 0,5 %
CVE de référenceNVD2026-07-11CVE-2026-61447

La leçon ne porte pas sur un framework en particulier. Chaque fois que vous laissez un modèle de langage écrire du code puis l’exécuter, vous avez fait passer l’injection de prompt de « le modèle a dit quelque chose de mal » à « le modèle a fait quelque chose de mal ». La défense durable consiste à supposer que l’injection réussira et à s’assurer que le code produit s’exécute là où il ne peut pas vous nuire.

Sources