Skip to content

CVE-2026-40087: LangChain Incomplete f-string Validation & Attribute Exposure

HERMES

HERMES THREAT SCORE & AGENTIC RISK

Target: LangChain Prompt Template Engine (DictPromptTemplate & ImagePromptTemplate)
Confidence: 97%
72 / 100
HIGH

Measures real-world operational relevance, exploit weaponization, and active threat posture.

Dimension Breakdown
Exploitability 16 / 20
Threat Activity 12 / 20
Weaponization 14 / 20
Exposure 15 / 20
Prevalence 18 / 20
Impact 12 / 20
Exploit Maturity 11 / 20
Attack Chain Potential 14 / 20
⚖️ Divergence & Operational Rationale

While NVD assigns a moderate CVSS 5.3 base score (considering confidentiality only under single-tenant conditions), Hermes Threat Score rates this vulnerability at 72 (HIGH). In autonomous agent architectures, prompt templates frequently bind high-privilege tool kwargs, internal state objects, and database tokens that an adversary can reflect directly into model attention context.

🕸️ Connected Knowledge Graph & Provenance

CVE-2026-40087: LangChain Incomplete f-string Validation & Attribute ExposureVULNERABILITY

Connected Nodes: 5
Active Relationships (Outgoing)
→ affectsPRODUCTLangChain & LangGraph Framework
99% VERY_HIGH

Multi-agent coordination framework and cyclic state graph orchestration engine for tool-calling agents.

🔍 Why is this related? (Evidence & Provenance)

“Directly impacts langchain and langchain-core prompt template engine prior to versions 0.3.84 and 1.2.28.”

Supporting Verified Evidence:
→ exploitsAGENTIC ATTACK_PATTERNAAP-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.

🔍 Why is this related? (Evidence & Provenance)

“Untrusted prompt template strings allow injecting format specifiers that subvert system prompt boundaries and access internal object properties.”

Supporting Verified Evidence:
→ affectsPRODUCTLangChain & LangGraph Framework
98% VERY_HIGH

Multi-agent coordination framework and cyclic state graph orchestration engine for tool-calling agents.

🔍 Why is this related? (Evidence & Provenance)

“Confirmed security vulnerability in LangGraph Multi-Agent Runtime documented in Hermes dossier.”

Supporting Verified Evidence:
→ exploitsAGENTIC ATTACK_PATTERNAAP-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.

🔍 Why is this related? (Evidence & Provenance)

“CVE-2026-40087 weaponizes the agentic attack pattern formalized under AAP-001.”

Supporting Verified Evidence:
→ exploitsAGENTIC ATTACK_PATTERNAAP-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.

🔍 Why is this related? (Evidence & Provenance)

“CVE-2026-40087 weaponizes the agentic attack pattern formalized under AAP-002.”

Supporting Verified Evidence:

1. Architectural Context: Dynamic Prompt Templates in LangChain

Section titled “1. Architectural Context: Dynamic Prompt Templates in LangChain”

In the LangChain orchestration framework, prompt templates format user and system inputs before feeding them to foundation models or agent loops:

Untrusted Prompt Template String (e.g. from Custom Workflow / User Config)
│
▼
LangChain Core Template Engine (DictPromptTemplate / ImagePromptTemplate)
│
▼ (Missing Attribute & Nested Specifier Checks)
Python str.format() / f-string Evaluation
│
▼
Access to Bound Python Object State (.__class__, __dict__, additional_kwargs)
│
▼
Leaked Internal Object Data Injected into LLM Context / Model Prompts

LangChain provides multiple specialized prompt classes:

  • PromptTemplate: The standard string-based template class, which implemented explicit AST inspection to ban attribute access (.) and indexing ([]).
  • DictPromptTemplate: Formats dictionary-like schema representations, often used in structured outputs and tool call arguments.
  • ImagePromptTemplate: Formats URLs or base64 multimodal image references for vision-capable models.

While PromptTemplate enforced guardrails, DictPromptTemplate and ImagePromptTemplate bypassed these validations during template instantiation and deserialization.


2. Root Cause Analysis: The Two Validation Gaps

Section titled “2. Root Cause Analysis: The Two Validation Gaps”

In versions prior to the patch, DictPromptTemplate and ImagePromptTemplate accepted f-string formatting directives without passing the template strings through validate_template_format. Consequently, expressions that traversed object hierarchies survived construction:

# Vulnerable template pattern in DictPromptTemplate / ImagePromptTemplate
template = ImagePromptTemplate(
template="https://api.internal/assets/{user_session.__class__.__init__.__globals__[API_KEY]}.png"
)

When formatted with an active application session object, Python’s runtime format resolver evaluated the expression, exposing sensitive global environment mappings directly into the resulting URL or payload.

The second flaw affected the core f-string parsing mechanism itself. LangChain validated input field names by checking top-level variable identifiers returned by Python’s string.Formatter().parse() method.

However, Python f-strings permit nested replacement fields within format specifiers:

# Format specifier evasion payload
f_string_payload = "{name:{name.__class__.__name__}}"

In standard string parsing:

  1. name is parsed as the primary replacement field (which passes allowlist validation).
  2. The format specifier {name.__class__.__name__} is treated as an auxiliary formatting parameter.
  3. At runtime, str.format() resolves the nested replacement field first, executing the inner attribute traversal and leaking the Python class name or evaluating nested attributes.

In agentic workflows, this vulnerability connects directly to AAP-001: Direct System Prompt Override and AAP-002: Indirect Context Injection:

[Adversary supplies custom template via collaborative agent workspace]
│
▼
[Application binds LangChain Execution Context Object into template parameters]
│
▼
[CVE-2026-40087: Nested format specifier extracts internal credentials]
│
▼
[Prompt sent to LLM contains leaked internal secrets in cleartext]
│
▼
[Agent tool or LLM response echoes credentials back to user or logs]
  1. Template Delivery: The attacker provides a prompt template containing nested format specifiers ({item:{item.__dict__}}) via a custom workflow editor or imported JSON recipe.
  2. Context Binding: The application executes the template pipeline, passing rich runtime objects (such as AIMessage, AgentExecutorState, or database connection metadata).
  3. Internal Traversal: The format resolver processes the nested specifier, extracting object state and private attributes.
  4. Context Exfiltration: The evaluated string is either passed to the model (which echoes or uses the data in subsequent tool invocations) or logged in plaintext monitoring traces.

title: LangChain Insecure f-string Template Pattern Ingestion
id: 9a81b234-7123-4c91-b301-8192fa400087
status: experimental
description: Detects nested format specifiers and forbidden attribute traversal within serialized LangChain prompt template definitions.
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

Update langchain and langchain-core to the patched releases:

Terminal window
pip install --upgrade "langchain>=0.3.84" "langchain-core>=0.3.84"
# Or for 1.2.x line:
pip install --upgrade "langchain>=1.2.28" "langchain-core>=1.2.28"

The vendor patch enforces two concrete verification stages:

  1. Rejection of field identifiers containing attribute operators (.) or index brackets ([]) across all prompt template subclasses.
  2. Explicit rejection of curly braces ({ or }) within format specifier segments.
  • Primitive Value Binding: Never pass rich runtime instances (e.g. Client, Session, Connection) into template formatting dictionaries. Only pass explicit scalar primitives (str, int, float).
  • Template Schema Locking: Treat prompt templates as immutable code assets stored in version control rather than dynamically accepted runtime user inputs.