Aller au contenu

CVE-2026-40087 : validation incomplète des f-strings dans LangChain et fuite d'attributs

HERMES

SCORE DE MENACE HERMES & RISQUE AGENTIQUE

Cible : Moteur de Templates de Prompts LangChain (DictPromptTemplate & ImagePromptTemplate)
Confiance : 97%
72 / 100
ÉLEVÉ

Mesure la pertinence opérationnelle réelle, la militarisation de l'exploit et la posture de menace active.

Décomposition des dimensions
Exploitabilité 16 / 20
Activité de menace 12 / 20
Militarisation 14 / 20
Exposition 15 / 20
Prévalence 18 / 20
Impact 12 / 20
Maturité de l'exploit 11 / 20
Potentiel d'attaque en chaîne 14 / 20
⚖️ Divergence & Justification opérationnelle

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.

🕸️ Graphe de connaissances connecté & Provenance

CVE-2026-40087: LangChain Incomplete f-string Validation & Attribute ExposureVULNÉRABILITÉ

Nœuds connectés : 5
Relations sortantes actives
→ affectsCOMPOSANTLangChain & LangGraph Framework
99% VERY_HIGH

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.”

Preuves vérifiées associées :
→ exploitsMODÈLE D'ATTAQUEAAP-001: Direct System Prompt Override
91% 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.”

Preuves vérifiées associées :
→ affectsCOMPOSANTLangChain & LangGraph Framework
98% 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.”

Preuves vérifiées associées :
→ exploitsMODÈLE D'ATTAQUEAAP-001: Direct System Prompt Override
92% 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.”

Preuves vérifiées associées :
→ exploitsMODÈLE D'ATTAQUEAAP-002: Indirect Context Injection
92% VERY_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.”

Preuves vérifiées associées :

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 / Logs

LangChain 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 »

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 / ImagePromptTemplate
template = 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 format
f_string_payload = "{name:{name.__class__.__name__}}"

Lors de l’analyse :

  1. name est reconnu comme champ principal valide.
  2. Le spécificateur {name.__class__.__name__} est considéré comme un paramètre de mise en forme secondaire.
  3. À 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]
  1. 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.
  2. Liaison contextuelle : l’application traite le pipeline en passant des objets riches de runtime (AIMessage, AgentExecutorState, ou descripteurs de connexion).
  3. Traversée d’attributs : le moteur de formatage évalue l’expression imbriquée et extrait l’état privé de l’objet.
  4. Exfiltration : la chaîne résultante est injectée dans le prompt du LLM ou enregistrée dans les journaux d’audit.

title: Ingestion de Modèles f-string Incursifs dans LangChain
id: 9a81b234-7123-4c91-b301-8192fa400087
status: experimental
description: 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 Team
date: 2026-09-07
logsource:
category: application
product: langchain_pipeline
detection:
selection:
template_content|re:
- '\{[a-zA-Z0-9_]+:[^{}]*\{[^{}]+\}[^{}]*\}'
- '\{[a-zA-Z0-9_]+\.[a-zA-Z0-9_.]+\}'
- '\{[a-zA-Z0-9_]+\[[^\]]+\]\}'
condition: selection
fields:
- application_id
- template_id
- template_content
level: high
tags:
- attack.initial_access
- attack.t1190

Mettre à jour langchain et langchain-core vers les versions corrigées :

Fenêtre de terminal
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 :

  1. Rejet des identifiants de champs contenant des opérateurs de navigation (.) ou des crochets ([]) sur l’ensemble des sous-classes de templates.
  2. Rejet explicite des accolades ({ ou }) dans la section des spécificateurs de format.
  • 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.