Fedora Account System
Red Hat Associate
Red Hat Customer
Discovered as a part of project glasswing (ex-wing) render_template_to_json_file() performs a two-pass Jinja render: the first pass expands the template with user-supplied template_data, then the resulting string is wrapped in jinja2.Template() and rendered again. Because the default (non-sandboxed) Template class is used and DebugUndefined leaves unknown placeholders intact, any value in template_data that contains Jinja delimiters (e.g. in advisory.spec.synopsis / description / topic / content rendered by templates/advisory.yaml.jinja) becomes live template syntax in pass two. create_advisory.py invokes this path with advisory data sourced from release inputs, so a tenant able to influence those text fields can reach Python object-walk gadgets and execute arbitrary code inside the release-service-utils pod, which holds GitLab, Pyxis and signing credentials. *utils/apply_template.py:73-92 — output of pass 1 re-evaluated as a non-sandboxed Jinja template* ```python template = Template( template_file.read(), extensions=[AnsibleCoreFiltersExtension], undefined=DebugUndefined, ) ... content = template.render(template_data) ... # try 2nd pass content = Template(content).render(template_data) ```