LangChain Template Injection: CVE-2025-65106 Technical Analysis and Defense Guide

Quick Answer: The LangChain template injection vulnerability, CVE-2025-65106, is a high-severity flaw that allows attackers to execute arbitrary Python code inside an agent process by injecting malicious template variables. This vulnerability affects LangChain versions ≤0.3.79 and 1.0.0-1.0.6.

A high-severity template injection flaw (CVE-2025-65106) quietly shipped in LangChain ≤0.3.79 and 1.0.0-1.0.6, letting attackers break out of prompt templates and execute arbitrary Python inside your agent process. Because the exploit rides on ordinary-looking template variables, it can slip past prompt filters and travel through RAG pipelines, tool wrappers, or multi-agent message buses. If you run LangChain-backed assistants in production, treat this as an immediate patch-or-isolate event.

How the Attack Works

LangChain’s PromptTemplate engine compiles Jinja2-style strings into native Python before the LLM ever sees them. CVE-2025-65106 exists because user-supplied text can be placed inside double-curly braces {{ }} without further validation. An attacker who controls any field that ends up in the template—query parameters, document metadata, tool outputs, or even a chat message—can inject Python expressions that the template renderer will execute with the full privileges of the agent process.

A minimal proof-of-concept that exfiltrates the OPENAI_API_KEY environment variable looks like this:

{
  "user_query": "{{ self.__init__.__globals__.__builtins__.__import__('os').environ.get('OPENAI_API_KEY') }}"
}

When the prompt is rendered, the expression is evaluated and the key is interpolated into the prompt that is forwarded to the LLM, effectively leaking secrets in-band. More sophisticated payloads can write files, spawn reverse shells, or patch LangChain’s internal classes to persist across turns.

The vulnerability is especially sneaky inside Retrieval-Augmented Generation pipelines. A poisoned document stored in a vector DB can carry the payload in its metadata; when the retriever embeds that chunk into the prompt template, the injection fires without the end user ever typing a suspicious character.

Real-World Impact for Agent Deployments

Production agents often run with service-level cloud credentials and have network egress allowed to LLM endpoints, model registries, and internal APIs. Successful exploitation therefore grants an attacker a privileged foothold that can pivot laterally, steal model weights, or tamper with downstream tool calls. Because the exploit is “stateless” and travels inside the prompt itself, it propagates through multi-agent routers, shared memory stores, and even human-in-the-loop review steps.

Incident-response teams should assume that any user-controllable string that can reach a prompt template is a potential lateral movement channel. If you operate shared SaaS agents, one malicious customer can compromise the node running other tenants’ chains unless sandboxing is in place. Likewise, autonomous agents that browse the web or ingest third-party XML/JSON feeds can pull the payload from external content and self-compromise.

Immediate Defensive Measures

  1. Patch or pin: Upgrade to LangChain 0.3.80 or 1.0.7+ where the template renderer switches to a sandboxed Jinja2 environment that whitelists only safe builtins.
  2. Audit every PromptTemplate, ChatPromptTemplate, and FewShotPromptTemplate in your codebase for dynamic user input.
  3. Route templates that must remain dynamic through a sanitization wrapper that blocks curly braces and parentheses using a regex such as re.sub(r'[{}()]', '', untrusted).
  4. Drop ambient privileges: run agents inside containers with read-only root filesystems, no CAP_SYS_ADMIN, and secrets mounted through tmpfs rather than env vars.

A guardrail middleware pattern can add a second line of defense without touching every prompt:

from langchain.agents.middleware import after_agent, AgentState
from langchain.pydantic_v1 import BaseModel, ValidationError
import re, logging

class TemplateSafety(BaseModel):
    safe: bool
    reason: str | None = None

@after_agent
def template_safety_guard(ctx: AgentState) -> AgentState:
    last_msg = ctx.messages[-1].content
    if re.search(r'\{\{.*[_(].*\}\}', last_msg):
        logging.warning("Template injection signature detected, refusing")
        ctx.messages[-1].content = "Request blocked by security policy."
    return ctx

# Register globally
from langgraph.runtime import Runtime
Runtime.register_middleware(template_safety_guard)

This intercepts any agent message that contains {{ followed by underscores or parentheses—strong indicators of attribute traversal—and replaces it with a safe refusal before the prompt reaches the LLM.

Longer-Term Hardening Patterns

Shift templates from runtime strings to compile-time constants stored in version-controlled YAML. Adopt the principle of least power: if you only need variable substitution, use Python’s built-in string.Template with the safe_substitute method instead of Jinja2. When dynamic logic is unavoidable, ship it as a signed, audited template file and verify its hash at startup.

Consider moving sensitive tool execution to a micro-service that holds the credentials and communicates with the agent over a tightly scoped gRPC interface. Even if template injection occurs, the attacker remains inside the prompt layer and cannot directly touch the key material.

Finally, add structured observability: emit a post-render prompt checksum and length metric. Sudden spikes or checksum drift across identical user queries can reveal ongoing exploit attempts and let you revoke sessions before damage propagates.

Key Takeaways

  • CVE-2025-65106 is a code-execution vector hidden in plain template syntax; it affects every LangChain release through 0.3.79 and 1.0.6.
  • Upgrade to 0.3.80/1.0.7 or later immediately, then audit your prompt paths for user-controlled injection surfaces.
  • Combine patching with runtime guardrails, sandboxed containers, and template allow-lists to shrink the blast radius of future parser bugs.

For the official advisory and patch diff, see the NVD entry at https://nvd.nist.gov/vuln/detail/CVE-2025-65106.

Understand What Your Agent Is Actually Doing

AgentGuard360 monitors the full agent footprint: packages installed, files accessed, credentials touched, API calls made, tokens spent. See it, track it, and know when something changes.

Coming Soon

Frequently Asked Questions

What is the LangChain template injection vulnerability?

The LangChain template injection vulnerability, CVE-2025-65106, is a high-severity flaw that allows attackers to execute arbitrary Python code inside an agent process by injecting malicious template variables. This vulnerability affects LangChain versions ≤0.3.79 and 1.0.0-1.0.6.

How does the LangChain template injection attack work?

The attack works by injecting Python expressions inside double-curly braces {{ }} in user-supplied text, which are then executed by the template renderer with the full privileges of the agent process.

What are the potential consequences of the LangChain template injection vulnerability?

The potential consequences of the vulnerability include secret exfiltration, file writing, reverse shell spawning, and patching LangChain’s internal classes to persist across turns.