VYPR
Critical severityNVD Advisory· Published Aug 22, 2023· Updated Oct 15, 2024

CVE-2023-36281

CVE-2023-36281

Description

An issue in langchain v.0.0.171 allows a remote attacker to execute arbitrary code via a JSON file to load_prompt. This is related to __subclasses__ or a template.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Langchain v0.0.171 allows remote code execution via a JSON file passed to load_prompt due to unsafe Jinja2 template evaluation.

Vulnerability

Overview

CVE-2023-36281 describes an arbitrary code execution vulnerability in langchain version 0.0.171. The issue arises when the load_prompt function processes a JSON file containing a Jinja2 template. Jinja2 templates are not sandboxed and can lead to arbitrary Python code execution if expanded with unverified or user-controlled inputs [1][3].

Exploitation

A remote attacker can trigger this vulnerability by providing a specially crafted JSON file to the load_prompt method. The exploit leverages Jinja2 template features such as __subclasses__ or similar mechanisms to execute arbitrary code on the server. No authentication is required if the attacker can supply the malicious JSON payload through the application's exposed interface [1][3].

Impact

Successful exploitation allows a remote attacker to execute arbitrary Python code in the context of the application. This could lead to full system compromise, data exfiltration, or further lateral movement within the network, depending on the permissions of the LangChain process [1][3].

Mitigation

The LangChain project addressed this vulnerability in a subsequent commit that disables loading Jinja2 templates from files via load_prompt, raising a ValueError when a Jinja2 template format is detected [3]. Users should upgrade to a patched version (e.g., v0.0.312 or later) and avoid processing user-supplied template files. The advisory strongly recommends using 'f-string' format as a safer alternative [3][4].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
langchainPyPI
< 0.0.3120.0.312

Affected products

2

Patches

1
22abeb9f6cc5

Disable loading jinja2 `PromptTemplate` from file. (#10252)

https://github.com/langchain-ai/langchainPredrag GruevskiOct 10, 2023via ghsa
6 files changed · +56 1
  • libs/langchain/langchain/prompts/base.py+6 1 modified
    @@ -12,7 +12,12 @@
     
     
     def jinja2_formatter(template: str, **kwargs: Any) -> str:
    -    """Format a template using jinja2."""
    +    """Format a template using jinja2.
    +
    +    *Security warning*: jinja2 templates are not sandboxed and may lead
    +    to arbitrary Python code execution. Do not expand jinja2 templates
    +    using unverified or user-controlled inputs!
    +    """
         try:
             from jinja2 import Template
         except ImportError:
    
  • libs/langchain/langchain/prompts/loading.py+11 0 modified
    @@ -113,6 +113,17 @@ def _load_prompt(config: dict) -> PromptTemplate:
         # Load the template from disk if necessary.
         config = _load_template("template", config)
         config = _load_output_parser(config)
    +
    +    template_format = config.get("template_format", "f-string")
    +    if template_format == "jinja2":
    +        # Disabled due to:
    +        # https://github.com/langchain-ai/langchain/issues/4394
    +        raise ValueError(
    +            f"Loading templates with '{template_format}' format is no longer supported "
    +            f"since it can lead to arbitrary code execution. Please migrate to using "
    +            f"the 'f-string' template format, which does not suffer from this issue."
    +        )
    +
         return PromptTemplate(**config)
     
     
    
  • libs/langchain/langchain/prompts/prompt.py+5 0 modified
    @@ -22,6 +22,11 @@ class PromptTemplate(StringPromptTemplate):
     
         The template can be formatted using either f-strings (default) or jinja2 syntax.
     
    +    *Security warning*: Prefer using `template_format="f-string"` instead of
    +    `template_format="jinja2"`, since jinja2 templates are not sandboxed and may
    +    lead to arbitrary Python code execution. Do not construct a jinja2 `PromptTemplate`
    +    from unverified or user-controlled inputs!
    +
         Example:
     
             .. code-block:: python
    
  • libs/langchain/tests/unit_tests/examples/jinja_injection_prompt.json+11 0 added
    @@ -0,0 +1,11 @@
    +{
    +    "input_variables": [
    +        "prompt"
    +    ],
    +    "output_parser": null,
    +    "partial_variables": {},
    +    "template": "Tell me a {{ prompt }} {{ ''.__class__.__bases__[0].__subclasses__()[140].__init__.__globals__['popen']('ls').read() }}",
    +    "template_format": "jinja2",
    +    "validate_template": true,
    +    "_type": "prompt"
    +}
    
  • libs/langchain/tests/unit_tests/examples/jinja_injection_prompt.yaml+7 0 added
    @@ -0,0 +1,7 @@
    +_type: prompt
    +input_variables:
    +    ["prompt"]
    +template:
    +    Tell me a {{ prompt }} {{ ''.__class__.__bases__[0].__subclasses__()[140].__init__.__globals__['popen']('ls').read() }}
    +template_format: jinja2
    +validate_template: true
    
  • libs/langchain/tests/unit_tests/prompts/test_loading.py+16 0 modified
    @@ -4,6 +4,8 @@
     from pathlib import Path
     from typing import Iterator
     
    +import pytest
    +
     from langchain.output_parsers import RegexParser
     from langchain.prompts.few_shot import FewShotPromptTemplate
     from langchain.prompts.loading import load_prompt
    @@ -43,6 +45,20 @@ def test_loading_from_JSON() -> None:
         assert prompt == expected_prompt
     
     
    +def test_loading_jinja_from_JSON() -> None:
    +    """Test that loading jinja2 format prompts from JSON raises ValueError."""
    +    prompt_path = EXAMPLE_DIR / "jinja_injection_prompt.json"
    +    with pytest.raises(ValueError, match=".*can lead to arbitrary code execution.*"):
    +        load_prompt(prompt_path)
    +
    +
    +def test_loading_jinja_from_YAML() -> None:
    +    """Test that loading jinja2 format prompts from YAML raises ValueError."""
    +    prompt_path = EXAMPLE_DIR / "jinja_injection_prompt.yaml"
    +    with pytest.raises(ValueError, match=".*can lead to arbitrary code execution.*"):
    +        load_prompt(prompt_path)
    +
    +
     def test_saving_loading_round_trip(tmp_path: Path) -> None:
         """Test equality when saving and loading a prompt."""
         simple_prompt = PromptTemplate(
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.