CVE-2026-40087: LangChain Incomplete f-string Validation & Attribute Exposure
HERMES THREAT SCORE & AGENTIC RISK
Target:LangChain Prompt Template Engine (DictPromptTemplate & ImagePromptTemplate) 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.
CVE-2026-40087: LangChain Incomplete f-string Validation & Attribute ExposureVULNERABILITY
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.”
- [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) (Reliability: 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.”
- [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) (Reliability: 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.”
- [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 (Reliability: 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.”
- [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 (Reliability: 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.”
- [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 (Reliability: HIGH)
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 PromptsLangChain 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”A. Inconsistent Class Guardrails
Section titled “A. Inconsistent Class Guardrails”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 / ImagePromptTemplatetemplate = 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.
B. Nested Format Specifier Evasion
Section titled “B. Nested Format Specifier Evasion”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 payloadf_string_payload = "{name:{name.__class__.__name__}}"In standard string parsing:
nameis parsed as the primary replacement field (which passes allowlist validation).- The format specifier
{name.__class__.__name__}is treated as an auxiliary formatting parameter. - 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.
3. Attack Chain & Exploitation Scenario
Section titled “3. Attack Chain & Exploitation Scenario”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]Attack Flow Steps
Section titled “Attack Flow Steps”- Template Delivery: The attacker provides a prompt template containing nested format specifiers (
{item:{item.__dict__}}) via a custom workflow editor or imported JSON recipe. - Context Binding: The application executes the template pipeline, passing rich runtime objects (such as
AIMessage,AgentExecutorState, or database connection metadata). - Internal Traversal: The format resolver processes the nested specifier, extracting object state and private attributes.
- 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.
4. Detection Engineering
Section titled “4. Detection Engineering”title: LangChain Insecure f-string Template Pattern Ingestionid: 9a81b234-7123-4c91-b301-8192fa400087status: experimentaldescription: Detects nested format specifiers and forbidden attribute traversal within serialized LangChain prompt template definitions.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: """ Strictly verifies that an f-string template contains no attribute access, no subscripting, and no nested replacement fields inside format specifiers. """ formatter = string.Formatter() for literal_text, field_name, format_spec, conversion in formatter.parse(template_str): if field_name is not None: # Reject attribute traversal or dict indexing if "." in field_name or "[" in field_name: raise ValueError(f"Prohibited attribute access in field: {field_name}") if format_spec is not None: # Reject nested replacement fields in format specifiers if "{" in format_spec or "}" in format_spec: raise ValueError(f"Prohibited nested replacement field in format spec: {format_spec}") return True5. Remediation & Hardened Defense
Section titled “5. Remediation & Hardened Defense”A. Official Patch Upgrade
Section titled “A. Official Patch Upgrade”Update langchain and langchain-core to the patched releases:
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:
- Rejection of field identifiers containing attribute operators (
.) or index brackets ([]) across all prompt template subclasses. - Explicit rejection of curly braces (
{or}) within format specifier segments.
B. Architectural Isolation
Section titled “B. Architectural Isolation”- 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.