CVE-2026-40087 : validation incomplète des f-strings dans LangChain et fuite d'attributs
SCORE DE MENACE HERMES & RISQUE AGENTIQUE
Cible :Moteur de Templates de Prompts LangChain (DictPromptTemplate & ImagePromptTemplate) Tandis que le NVD attribue un score CVSS modéré de 5.3 (en se limitant à la confidentialité dans des configurations isolées), le score Hermes Threat évalue cette vulnérabilité à 72 (ÉLEVÉ). Dans les architectures d'agents autonomes, les templates de prompts intègrent couramment des arguments d'outils hautement privilégiés, des états de mémoire et des jetons d'accès qu'un attaquant peut injecter directement dans le contexte d'attention du modèle.
CVE-2026-40087: LangChain Incomplete f-string Validation & Attribute ExposureVULNÉRABILITÉ
Multi-agent coordination framework and cyclic state graph orchestration engine for tool-calling agents.
🔍 Pourquoi cette relation ? (Preuves & Provenance)
“Directly impacts langchain and langchain-core prompt template engine prior to versions 0.3.84 and 1.2.28.”
- [vendor_confirmation]LangChain confirmed DictPromptTemplate and ImagePromptTemplate evaluated attribute access and nested format specifiers at runtime without sanitization. — Source : LangChain AI Security Team: Incomplete f-string validation in prompt templates (GHSA-926x-3r5x-gfhw / CVE-2026-40087) (Fiabilité : VERY_HIGH)
Adversary injects explicit formatting tags or role-inversion prompts directly into user input to strip system instructions and escape developer-enforced guardrails.
🔍 Pourquoi cette relation ? (Preuves & Provenance)
“Untrusted prompt template strings allow injecting format specifiers that subvert system prompt boundaries and access internal object properties.”
- [vendor_confirmation]LangChain confirmed DictPromptTemplate and ImagePromptTemplate evaluated attribute access and nested format specifiers at runtime without sanitization. — Source : LangChain AI Security Team: Incomplete f-string validation in prompt templates (GHSA-926x-3r5x-gfhw / CVE-2026-40087) (Fiabilité : VERY_HIGH)
Multi-agent coordination framework and cyclic state graph orchestration engine for tool-calling agents.
🔍 Pourquoi cette relation ? (Preuves & Provenance)
“Confirmed security vulnerability in LangGraph Multi-Agent Runtime documented in Hermes dossier.”
- [vulnerability_report]
- [government_confirmation]CISA verified active exploitation in the wild and mandated federal remediation deadline in KEV entry. — Source : Cybersecurity & Infrastructure Security Agency (CISA): CISA Adds CVE-2026-59822 to Known Exploited Vulnerabilities Catalog (Fiabilité : VERY_HIGH)
Adversary injects explicit formatting tags or role-inversion prompts directly into user input to strip system instructions and escape developer-enforced guardrails.
🔍 Pourquoi cette relation ? (Preuves & Provenance)
“CVE-2026-40087 weaponizes the agentic attack pattern formalized under AAP-001.”
- [technical_analysis]Pillar Security demonstrated that executing export BASH_ENV in Auto-Run causes bash to source hostile payloads upon subsequent commands. — Source : Pillar Security Research: Bypassing Cursor Auto-Run: When Shell Built-ins Lead to Host RCE (Fiabilité : HIGH)
Adversary embeds covert payload instructions into retrieved external data (web pages, repositories, emails) that subvert model planning when parsed by autonomous agents.
🔍 Pourquoi cette relation ? (Preuves & Provenance)
“CVE-2026-40087 weaponizes the agentic attack pattern formalized under AAP-002.”
- [technical_analysis]Pillar Security demonstrated that executing export BASH_ENV in Auto-Run causes bash to source hostile payloads upon subsequent commands. — Source : Pillar Security Research: Bypassing Cursor Auto-Run: When Shell Built-ins Lead to Host RCE (Fiabilité : HIGH)
1. Contexte architectural : les templates de prompts dans LangChain
Section intitulée « 1. Contexte architectural : les templates de prompts dans LangChain »Dans l’écosystème LangChain, les templates de prompts assurent l’assemblage et la structuration des variables avant transmission aux modèles de fondation ou aux boucles agentiques :
Chaîne de Template Non Fiable (ex: importée depuis un flux ou un utilisateur) │ ▼ Moteur de Templates LangChain (DictPromptTemplate / ImagePromptTemplate) │ ▼ (Absence de filtrage des attributs et spécificateurs imbriqués) Évaluation native Python (str.format() / f-string) │ ▼ Accès aux Attributs de l'Objet Python (.__class__, __dict__, additional_kwargs) │ ▼ Fuite d'Informations Internes Intégrée au Contexte LLM / LogsLangChain propose plusieurs variantes de templates :
PromptTemplate: la classe standard pour chaînes textuelles, dotée d’une vérification stricte rejetant l’accès aux attributs (.) et l’indexation ([]).DictPromptTemplate: dédiée à la structuration sous forme de dictionnaire, fréquemment utilisée pour les arguments d’appels de fonctions (tool calls).ImagePromptTemplate: dédiée au formatage d’URL ou d’images encodées en base64 pour les modèles multimodaux.
Alors que PromptTemplate appliquait des garde-fous rigoureux, DictPromptTemplate et ImagePromptTemplate contournaient ces contrôles lors de leur instanciation et de leur désérialisation.
2. Analyse de la cause racine : les deux lacunes de validation
Section intitulée « 2. Analyse de la cause racine : les deux lacunes de validation »A. Incohérence des garde-fous selon la classe
Section intitulée « A. Incohérence des garde-fous selon la classe »Avant le correctif, DictPromptTemplate et ImagePromptTemplate acceptaient des expressions de formatage f-string sans les soumettre à la fonction validate_template_format. Par conséquent, des expressions traversant la hiérarchie des objets survivaient à l’instanciation :
# Modèle vulnérable dans DictPromptTemplate / ImagePromptTemplatetemplate = ImagePromptTemplate( template="https://api.internal/assets/{user_session.__class__.__init__.__globals__[API_KEY]}.png")Lors du formatage avec une session utilisateur active, le résolveur d’expression Python exécutait la navigation dans les attributs, injectant la clé secrète directement dans l’URL générée.
B. Évasion par spécificateur de format imbriqué
Section intitulée « B. Évasion par spécificateur de format imbriqué »La seconde faille touchait le parseur central de f-strings. LangChain vérifiait uniquement les identifiants de variables de premier niveau renvoyés par string.Formatter().parse().
Cependant, la syntaxe des f-strings Python autorise des champs de remplacement imbriqués dans les spécificateurs de format :
# Charge utile exploitant le spécificateur de formatf_string_payload = "{name:{name.__class__.__name__}}"Lors de l’analyse :
nameest reconnu comme champ principal valide.- Le spécificateur
{name.__class__.__name__}est considéré comme un paramètre de mise en forme secondaire. - À l’exécution,
str.format()résout d’abord l’expression imbriquée, ce qui évalue l’accès aux attributs internes et divulgue le nom de classe ou la structure mémoire.
3. Chaîne d’attaque & scénario d’exploitation
Section intitulée « 3. Chaîne d’attaque & scénario d’exploitation »Dans les environnements d’agents IA, cette vulnérabilité s’articule directement avec AAP-001 : écrasement direct de consignes et AAP-002 : injection indirecte contextuelle :
[L'adversaire injecte un template piégé via un espace de travail collaboratif] │ ▼[L'application injecte des objets d'exécution LangChain dans les paramètres du template] │ ▼[CVE-2026-40087 : Le spécificateur de format extrait les attributs confidentiels] │ ▼[Le prompt transmis au modèle contient les secrets internes en clair] │ ▼[L'agent ou le modèle répercute ces secrets dans sa réponse ou dans les logs]Étapes de la chaîne d’exploitation
Section intitulée « Étapes de la chaîne d’exploitation »- Dépôt du template : l’attaquant soumet un template contenant des spécificateurs imbriqués (
{item:{item.__dict__}}) via un éditeur de workflow ou une configuration JSON. - Liaison contextuelle : l’application traite le pipeline en passant des objets riches de runtime (
AIMessage,AgentExecutorState, ou descripteurs de connexion). - Traversée d’attributs : le moteur de formatage évalue l’expression imbriquée et extrait l’état privé de l’objet.
- Exfiltration : la chaîne résultante est injectée dans le prompt du LLM ou enregistrée dans les journaux d’audit.
4. Ingénierie de détection
Section intitulée « 4. Ingénierie de détection »title: Ingestion de Modèles f-string Incursifs dans LangChainid: 9a81b234-7123-4c91-b301-8192fa400087status: experimentaldescription: Détecte les spécificateurs de format imbriqués et les traversées d'attributs interdites dans les définitions de templates de prompts LangChain.author: Hermes Codex Research Teamdate: 2026-09-07logsource: category: application product: langchain_pipelinedetection: selection: template_content|re: - '\{[a-zA-Z0-9_]+:[^{}]*\{[^{}]+\}[^{}]*\}' - '\{[a-zA-Z0-9_]+\.[a-zA-Z0-9_.]+\}' - '\{[a-zA-Z0-9_]+\[[^\]]+\]\}' condition: selectionfields: - application_id - template_id - template_contentlevel: hightags: - attack.initial_access - attack.t1190import stringfrom typing import Set
def validate_fstring_template_strict(template_str: str) -> bool: """ Vérifie rigoureusement qu'un template f-string ne comporte aucun accès d'attribut, aucune indexation et aucun champ de remplacement imbriqué dans les spécificateurs. """ formatter = string.Formatter() for literal_text, field_name, format_spec, conversion in formatter.parse(template_str): if field_name is not None: # Rejeter la traversée d'attributs ou l'indexation de dictionnaires if "." in field_name or "[" in field_name: raise ValueError(f"Accès d'attribut interdit dans le champ : {field_name}") if format_spec is not None: # Rejeter les champs de remplacement imbriqués dans les spécificateurs if "{" in format_spec or "}" in format_spec: raise ValueError(f"Champ de remplacement imbriqué interdit dans le spécificateur : {format_spec}") return True5. Mesures de correction & durcissement
Section intitulée « 5. Mesures de correction & durcissement »A. Mise à niveau officielle
Section intitulée « A. Mise à niveau officielle »Mettre à jour langchain et langchain-core vers les versions corrigées :
pip install --upgrade "langchain>=0.3.84" "langchain-core>=0.3.84"# Ou pour la branche 1.2.x :pip install --upgrade "langchain>=1.2.28" "langchain-core>=1.2.28"Le correctif applique deux vérifications impératives :
- Rejet des identifiants de champs contenant des opérateurs de navigation (
.) ou des crochets ([]) sur l’ensemble des sous-classes de templates. - Rejet explicite des accolades (
{ou}) dans la section des spécificateurs de format.
B. Isolation architecturale
Section intitulée « B. Isolation architecturale »- Liaison scalaire primitive : ne jamais passer d’instances d’objets complexes (ex:
Client,Session,Connection) dans les dictionnaires de variables de templates ; restreindre aux scalaires (str,int,float). - Verrouillage de schéma : considérer les templates de prompts comme du code statique immuable sous contrôle de version, et non comme des données dynamiques saisies par l’utilisateur.