EresusSecurity

Jinja2 Template Rules

Detects server-side template injection and unsafe template constructs in prompt, chat, and report templates.

Definition

The Jinja2 rule family turns findings on this surface into actionable records with rule ID, severity, CWE, OWASP LLM mapping, owner, release decision, and retest command.

Jinja2 templates appear in chat templates, RAG prompts, dashboards, and report generation. Unsafe templates can expose secrets or execute code.

Canonical help URL

Supported inputs

  • .j2
  • .jinja
  • YAML prompt templates
  • GGUF tokenizer metadata
  • HTML report templates

Typical attack scenarios

  • A user-controlled prompt reaches a Jinja2 render call.
  • A model chat template contains object traversal primitives.
  • A report template exposes environment variables.

Detection logic

Sentinel ties Jinja2 evidence to reproducible signals such as file path, metadata, opcode, AST node, manifest field, dependency, or archive entry. The same signal should disappear when the finding is closed.

Triage

Do not read Jinja2 findings as scanner noise. Verify the evidence first, map the finding to a severity-based release decision, and then produce closure evidence with the same Sentinel command.

Operational checklist
  • Source: where did the file, manifest, prompt, archive, or dependency come from?
  • Impact: code execution, data leakage, supply chain, or resource consumption?
  • Control: allowlist, hash, sandbox, egress policy, or secret rotation?
  • Evidence: does the same rule category return clean after the fix?

Remediation

Remediation should change the risk boundary, not merely silence the finding: remove executable formats, pin source or hash, narrow tool permissions, rotate secrets, or add runtime sandboxing.

CI policy

sentinel-policy.yml
category: JINJA2
fail_on:
  - CRITICAL
  - HIGH
ticket_on:
  - MEDIUM
retest: "sentinel sast ./src/ --rule JINJA2"

Rule index

Rule IDSeverityTitleCWEFix Hint
JINJA2-SSTI-001CRITICALServer-Side Template InjectionCWE-94Treat prompt templates as code and review them before load.
JINJA2-UNSANDBOXED-TEMPLATEHIGHUnsandboxed Jinja2 RenderingCWE-94Sandbox template rendering and avoid dynamic template strings.
JINJA2-SECRET-EXPOSUREHIGHTemplate Secret ExposureCWE-200Keep credentials out of render context.

JINJA2-SSTI-001Server-Side Template Injection

CRITICAL
Rule IDJINJA2-SSTI-001
CategoryJINJA2
SeverityCRITICAL
CWECWE-94
OWASP LLMLLM01 — Prompt Injection, LLM06 — Excessive Agency
FP RiskLOW
OwnerApplication security and backend/agent owner
Release decisionBlock release; do not promote the artifact or code path until it is isolated.

Description

Detects Jinja2 expressions that can traverse Python objects, access globals, or execute functions.

Why it matters

Jinja2 templates appear in chat templates, RAG prompts, dashboards, and report generation. Unsafe templates can expose secrets or execute code.

When it fires

Sentinel fires this rule in the Jinja2 category when it sees template tokens containing __class__, __mro__, __subclasses__, __globals__, cycler, joiner, or namespace abuse.. The finding should be reported with reproducible evidence such as file name, metadata, opcode, AST node, or manifest field.

Evidence format

Template tokens containing __class__, __mro__, __subclasses__, __globals__, cycler, joiner, or namespace abuse.

Expected evidence

The report should include the affected file or manifest path, observed signal, rule ID, severity, owner, and retest command required for closure.

False-positive notes

False-positive probability is low. If evidence points directly to a file, opcode, secret pattern, path, or manifest field, treat it as real and require closure evidence.

Triage

Operational checklist
  • Owner: Application security and backend/agent owner.
  • Decision: Block release; do not promote the artifact or code path until it is isolated.
  • Evidence: Template tokens containing __class__, __mro__, __subclasses__, __globals__, cycler, joiner, or namespace abuse.
  • Closure: sentinel sast ./src/ --rule JINJA2 must return clean output.

How to fix

Never render user-controlled templates. Use SandboxedEnvironment and pass a minimal validated context.

CLI

sentinel sast ./src/ --rule JINJA2

Policy example

sentinel-policy.yml
rules:
  JINJA2-SSTI-001:
    owner: "Application security and backend/agent owner"
    fail_on: ["CRITICAL", "HIGH"]
    retest: "sentinel sast ./src/ --rule JINJA2"

Expected output

JINJA2-SSTI-001 CRITICAL
Server-Side Template Injection
Treat prompt templates as code and review them before load.

Example

Bad
template = "{{ request.args.q }} {{ config.__class__.__init__.__globals__ }}"
render_template_string(template)
Good
env = SandboxedEnvironment(autoescape=True)
template = env.get_template("safe_prompt.j2")
template.render(validated_context)

Related rules

JINJA2-UNSANDBOXED-TEMPLATEUnsandboxed Jinja2 Rendering

HIGH
Rule IDJINJA2-UNSANDBOXED-TEMPLATE
CategoryJINJA2
SeverityHIGH
CWECWE-94
OWASP LLMLLM01 — Prompt Injection
FP RiskMEDIUM
OwnerApplication security and backend/agent owner
Release decisionTreat as a release gate; remediation or explicit risk acceptance is required.

Description

Flags Jinja2 render paths that use default Environment or render_template_string with untrusted template strings.

Why it matters

Jinja2 templates appear in chat templates, RAG prompts, dashboards, and report generation. Unsafe templates can expose secrets or execute code.

When it fires

Sentinel fires this rule in the Jinja2 category when it sees ast calls to environment(...), template(...), or render_template_string(...) without sandboxing and context validation.. The finding should be reported with reproducible evidence such as file name, metadata, opcode, AST node, or manifest field.

Evidence format

AST calls to Environment(...), Template(...), or render_template_string(...) without sandboxing and context validation.

Expected evidence

The report should include the affected file or manifest path, observed signal, rule ID, severity, owner, and retest command required for closure.

False-positive notes

False-positive probability is medium. Verify source, expected use, and owner first; add an allowlist if needed, but do not remove evidence from the report.

Triage

Operational checklist
  • Owner: Application security and backend/agent owner.
  • Decision: Treat as a release gate; remediation or explicit risk acceptance is required.
  • Evidence: AST calls to Environment(...), Template(...), or render_template_string(...) without sandboxing and context validation.
  • Closure: sentinel sast ./src/ --rule JINJA2 must return clean output.

How to fix

Use SandboxedEnvironment, fixed template files, strict undefined behavior, and schema-validated context objects.

CLI

sentinel sast ./src/ --rule JINJA2

Policy example

sentinel-policy.yml
rules:
  JINJA2-UNSANDBOXED-TEMPLATE:
    owner: "Application security and backend/agent owner"
    fail_on: ["CRITICAL", "HIGH"]
    retest: "sentinel sast ./src/ --rule JINJA2"

Expected output

JINJA2-UNSANDBOXED-TEMPLATE HIGH
Unsandboxed Jinja2 Rendering
Sandbox template rendering and avoid dynamic template strings.

Example

Bad
template = "{{ request.args.q }} {{ config.__class__.__init__.__globals__ }}"
render_template_string(template)
Good
env = SandboxedEnvironment(autoescape=True)
template = env.get_template("safe_prompt.j2")
template.render(validated_context)

Related rules

JINJA2-SECRET-EXPOSURETemplate Secret Exposure

HIGH
Rule IDJINJA2-SECRET-EXPOSURE
CategoryJINJA2
SeverityHIGH
CWECWE-200
OWASP LLMLLM02 — Sensitive Information Disclosure
FP RiskMEDIUM
OwnerApplication security and backend/agent owner
Release decisionTreat as a release gate; remediation or explicit risk acceptance is required.

Description

Detects templates that render environment variables, credentials, request headers, or internal config objects.

Why it matters

Jinja2 templates appear in chat templates, RAG prompts, dashboards, and report generation. Unsafe templates can expose secrets or execute code.

When it fires

Sentinel fires this rule in the Jinja2 category when it sees template references env, environ, secrets, config, headers, cookies, or token-like variables.. The finding should be reported with reproducible evidence such as file name, metadata, opcode, AST node, or manifest field.

Evidence format

Template references env, environ, secrets, config, headers, cookies, or token-like variables.

Expected evidence

The report should include the affected file or manifest path, observed signal, rule ID, severity, owner, and retest command required for closure.

False-positive notes

False-positive probability is medium. Verify source, expected use, and owner first; add an allowlist if needed, but do not remove evidence from the report.

Triage

Operational checklist
  • Owner: Application security and backend/agent owner.
  • Decision: Treat as a release gate; remediation or explicit risk acceptance is required.
  • Evidence: Template references env, environ, secrets, config, headers, cookies, or token-like variables.
  • Closure: sentinel sast ./src/ --rule JINJA2 must return clean output.

How to fix

Remove secrets from template context and pass only explicitly required display fields.

CLI

sentinel sast ./src/ --rule JINJA2

Policy example

sentinel-policy.yml
rules:
  JINJA2-SECRET-EXPOSURE:
    owner: "Application security and backend/agent owner"
    fail_on: ["CRITICAL", "HIGH"]
    retest: "sentinel sast ./src/ --rule JINJA2"

Expected output

JINJA2-SECRET-EXPOSURE HIGH
Template Secret Exposure
Keep credentials out of render context.

Example

Bad
template = "{{ request.args.q }} {{ config.__class__.__init__.__globals__ }}"
render_template_string(template)
Good
env = SandboxedEnvironment(autoescape=True)
template = env.get_template("safe_prompt.j2")
template.render(validated_context)

Related rules

References