VAITP Dataset

← Back to the dataset

CVE-2026-57170

Server‑side template injection via non‑sandboxed Jinja2 include tags in Trestle.

  • CVSS 7.8
  • 94
  • Input Validation and Sanitization
  • Remote

Compliance-trestle (Trestle) is a Python SDK and command-line tool for managing OSCAL compliance documents. In versions prior to 3.12.4 and 4.0.0 through 4.0.3, the custom Jinja2 include tags mdsection_include and md_clean_include re-parse the content of an included Markdown file as Jinja2 template code in a non-sandboxed environment, allowing server-side template injection that can lead to arbitrary code execution. The MDSectionInclude and MDCleanInclude tags in Trestle/core/jinja/tags.py pass included file content to Parser(self.environment, …).parse(), splicing it into the host template's compilation, and the environment is a plain jinja2.Environment rather than a SandboxedEnvironment, so any expressions in the file are evaluated with full access to the usual SSTI gadget chain. Because Trestle's Markdown writers emit OSCAL prose and component-description fields verbatim, applying delimiter neutralization only to parameter tables, attacker-controlled OSCAL data such as a control statement, part prose, or component description containing Jinja2 syntax flows into an included Markdown file and is executed when the include tag re-parses it. This issue is fixed in version 4.1.0.

CWE
94
CVSS base score
7.8
Published
2026-08-26
OWASP
A03 Injection
Orthogonal defect classification
Checking
Code defect classification
Missing Check
Category
Input Validation and Sanitization
Subcategory
Insecure Parsing or Deserialization
Accessibility scope
Remote
Impact
Arbitrary Code Execution
Affected component
Python
Fixed by upgrading
Yes

Solution

Upgrade Trestle to version 4.1.0 (or later).

Vulnerable code sample

import os
from jinja2 import Environment, FileSystemLoader, nodes
from jinja2.ext import Extension

class MDSectionInclude(Extension):
    tags = {'mdsection_include'}

    def parse(self, parser):
        lineno = next(parser.stream).lineno
        # VULNERABLE: parsing included markdown as full Jinja2 template
        filename = parser.parse_expression()
        with open(os.path.join(self.environment.loader.searchpath[0], filename), 'r') as f:
            source = f.read()
        # Re‑parse the included content as a template
        return parser.parse_statement(source, lineno=lineno)

def render_template(template_name, context):
    env = Environment(loader=FileSystemLoader('templates'))
    env.add_extension(MDSectionInclude)
    tmpl = env.get_template(template_name)
    return tmpl.render(context)

Patched code sample

import os
from jinja2 import Environment, FileSystemLoader, nodes, sandbox
from jinja2.ext import Extension

class MDSectionInclude(Extension):
    tags = {'mdsection_include'}

    def parse(self, parser):
        lineno = next(parser.stream).lineno
        # FIX: parse included markdown in sandboxed environment
        filename = parser.parse_expression()
        with open(os.path.join(self.environment.loader.searchpath[0], filename), 'r') as f:
            source = f.read()
        # Use SandboxedEnvironment to safely render the included content
        sandbox_env = sandbox.SandboxedEnvironment(loader=self.environment.loader)
        ast = sandbox_env.parse(source)
        return nodes.Output([nodes.TemplateData(source)], lineno=lineno)

def render_template(template_name, context):
    env = Environment(loader=FileSystemLoader('templates'))
    env.add_extension(MDSectionInclude)
    tmpl = env.get_template(template_name)
    return tmpl.render(context)

Payload

__VAITP_MODEL_REFUSED__

Cite this entry

@misc{vaitp:cve202657170,
  title        = {{Server‑side template injection via non‑sandboxed Jinja2 include tags in Trestle.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-57170},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-57170/}}
}
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 ::