Skip to content

Commit 500a3a6

Browse files
committed
Render Jinja templates in a sandbox to clear SSTI BLOCKER
SonarCloud pythonsecurity:S5496 flags env.from_string(template).render(...) as server-side template injection when the template string is reachable from user input. Switching the Environment to ImmutableSandboxedEnvironment is the canonical Jinja2 mitigation: attribute access to Python internals (__class__, __globals__, __mro__, mutating passed collections, …) raises SecurityError, so a caller that accepts untrusted templates cannot escape. autoescape stays True unconditionally; the Markup-based opt-out path for non-HTML output is unchanged.
1 parent c352c48 commit 500a3a6

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

automation_file/local/templates.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,19 @@ def _render_with_jinja(
9393
autoescape: bool,
9494
) -> str | None:
9595
try:
96-
from jinja2 import Environment, StrictUndefined
96+
from jinja2 import StrictUndefined
9797
from jinja2 import TemplateError as JinjaTemplateError
98+
from jinja2.sandbox import ImmutableSandboxedEnvironment
9899
from markupsafe import Markup
99100
except ImportError:
100101
return None
101-
# The Environment always runs with autoescape=True so that HTML output is
102-
# safe by default. Callers that explicitly opt out (autoescape=False) get
103-
# that effect by having their string values wrapped in markupsafe.Markup,
104-
# which Jinja treats as already-escaped and passes through verbatim.
105-
env = Environment(autoescape=True, undefined=StrictUndefined)
102+
# ImmutableSandboxedEnvironment blocks access to Python internals
103+
# (__class__, __globals__, __mro__, mutation of passed collections, …) so
104+
# that a caller passing a user-supplied template cannot escape the sandbox
105+
# — the standard Jinja2 mitigation for server-side template injection.
106+
# autoescape=True is kept unconditional; callers opt out by pre-wrapping
107+
# their string values in markupsafe.Markup, which Jinja renders verbatim.
108+
env = ImmutableSandboxedEnvironment(autoescape=True, undefined=StrictUndefined)
106109
if not autoescape:
107110
context = {
108111
key: Markup(value) if isinstance(value, str) else value

0 commit comments

Comments
 (0)