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

Prompts-shells : quand l'injection de prompt devient RCE dans les frameworks d'agents

Deux CVE divulguées dans Microsoft Semantic Kernel le 7 mai 2026 (CVE-2026-25592, CVE-2026-26030) montrent comment un prompt injecté peut basculer du texte à l'exécution de code à distance sur l'hôte de l'agent.

2026-05-22 // 8 min affects: semantic-kernel-python, semantic-kernel-dotnet, agent-frameworks

Ce qui s’est passé

Le 7 mai 2026, le Microsoft Security Response Center a publié deux vulnérabilités critiques dans le framework d’agents Semantic Kernel : CVE-2026-25592 (CVSS 10.0) dans le SDK .NET et CVE-2026-26030 (CVSS 9.8) dans le SDK Python. Les deux transforment une injection de prompt textuelle — le modèle recevant des instructions contrôlées par l’attaquant via du contenu non fiable — en exécution de code à distance sur la machine qui héberge l’agent. Les correctifs sont arrivés le jour même : semantic-kernel Python 1.39.4 et .NET 1.71.0.

Le billet de recherche associé, When prompts become shells, dégage un schéma plus large : les frameworks d’agents exposent au modèle un registre d’outils, de sandbox et de fonctions auxiliaires, et tout helper qui touche à un sink d’exécution de code (eval, exec, désérialisation, écriture fichier, shell) devient accessible par un simple prompt.

Mécanisme

Un agent fournit au LLM un registre d’outils appelables. Le modèle décide lesquels invoquer et passe les arguments. Deux bugs distincts, même forme :

CVE-2026-26030 — eval() Python dans le vector store en mémoire. Le composant InMemoryVectorStore par défaut construisait des expressions de filtrage en passant des chaînes influencées par l’attaquant dans un lambda Python compilé avec eval(). Un LLM piégé par un prompt injecté pouvait demander au store de filtrer des enregistrements avec un payload qui exécute du Python arbitraire.

# Schéma conceptuel — NE PAS exécuter.
# Un champ contrôlé par du contenu non fiable atteint eval().
filter_expr = f"lambda r: r.score > {model_supplied_value}"
predicate = eval(filter_expr)  # [REDACTED] : le payload s'exécute dans le processus hôte

CVE-2026-25592 — DownloadFileAsync exposé en tant que [KernelFunction] dans le sandbox .NET. Le SessionsPythonPlugin exécute le code généré par le modèle dans une session dynamique Azure Container Apps. Un helper interne, DownloadFileAsync, a été annoté [KernelFunction] par erreur et enregistré comme outil appelable, sans validation de chemin. Un prompt pouvait demander à l’agent de « télécharger » un fichier distant vers un chemin local arbitraire, écrivant du contenu attaquant hors du sandbox, sur l’hôte.

Dans les deux cas, le point d’entrée est du texte. Pas de corruption mémoire, pas d’exploit navigateur. Le modèle interprète la requête, choisit un outil, et passe les paramètres à un sink d’exécution.

Pourquoi c’est important

Ce n’est pas une histoire spécifique à Semantic Kernel. Le même schéma est revenu plusieurs fois en 2026 dans les frameworks d’agents (PraisonAI, Flowise, LMDeploy, mcp-remote — voir le tracker Adversa AI). La cause structurelle est identique :

  1. Le framework expose un registre d’outils au LLM.
  2. Au moins un outil atteint un sink dangereux (eval, exec, pickle, écriture de chemin, shell).
  3. L’agent traite du texte non fiable — documents récupérés, pages web, résultats d’outils — au même niveau que ses propres instructions.
  4. Aucune frontière n’est imposée entre données et instructions.

C’est exactement le lethal trifecta décrit par Simon Willison en juin 2025 — accès à des données privées, exposition à du contenu non fiable, capacité d’action externe — et la Règle de deux proposée par l’équipe AI Security de Meta le 31 octobre 2025 : un agent doit conserver au plus deux de ces trois propriétés par session. Quand les trois coexistent, la sécurité déterministe s’effondre et un prompt textuel devient un shell.

Défenses

Les mitigations sont architecturales, pas heuristiques — le filtrage de prompt ne suffit pas.

  1. Patcher d’abord. Mettre à jour Semantic Kernel en Python >=1.39.4 et .NET >=1.71.0. Auditer tout framework d’agents en production en s’appuyant sur le tracker mensuel d’Adversa.
  2. Bannir eval/exec sur des chaînes fournies par le modèle. Les remplacer par des parseurs structurés (allowlist AST, DSL de filtrage typé). Le correctif Microsoft empile quatre vérifications : allowlist de types de nœud AST, allowlist d’appels de fonction, blocklist d’attributs dangereux, restriction des nœuds nom.
  3. Auditer le registre d’outils. Chaque [KernelFunction], @tool ou endpoint OpenAPI exposé est accessible au modèle. Considérer le registre comme une API publique : surface minimale, paramètres validés, aucun helper exposé par accident.
  4. Sandboxer l’exécuteur, pas le prompt. Exécuter tout code piloté par le modèle dans un conteneur ou une microVM sans réseau, sans écriture hôte, sans credentials au-delà de la tâche.
  5. Appliquer la Règle de deux. Pour chaque session d’agent, décider quelles deux propriétés sur trois — {entrée non fiable, donnée sensible, action externe} — vous acceptez, et imposer la coupe au niveau architectural.
  6. Journaliser les appels d’outils avec leurs arguments complets. Permettre la détection a posteriori ; la sortie brute du modèle ne suffit pas.

État

FrameworkCVECVSSDivulgationCorrigé en
Semantic Kernel (.NET)CVE-2026-2559210.02026-05-071.71.0
Semantic Kernel (Python)CVE-2026-260309.82026-05-071.39.4
PraisonAICVE-2026-443389.x2026-04dernière version
Flowise MCP adapterCVE-2026-409339.x2026-04dernière version

Si vous exploitez un agent en production, la question n’est plus si une injection de prompt atteindra votre couche d’outils, mais sur quel sink elle va tomber. Coupez les sinks.

Sources