CVE-2026-84714: Automation-controller: automation-controller: incomplete sanitize_jinja() regex allows jinja template injection into ad-hoc module_args, machine-credential fields, and host names, reaching ansible-core templating in the execution environment
A flaw was found in the automation-controller input-validation guard sanitizejinja(). The function uses two regular expressions to reject user-supplied Jinja, but the patterns stop at the first interior '}' or '%' character, so a Jinja expression containing an inner brace (for example an empty dict) is accepted while remaining valid Jinja. Because sanitizejinja() is the sole guard on several launch-time fields — ad-hoc command moduleargs, Machine-credential username / becomemethod / becomeuser, and inventory host names — a low-privileged user can inject Jinja that ansible-core evaluates in the execution environment. This enables execution of arbitrary commands in the execution environment (bypassing an administrator's ADHOCCOMMANDS module allowlist) and disclosure of secrets belonging to credentials the attacker cannot read (by templating a co-attached credential's injected environment variables), across the credential access-control boundary.
Other sources
A template-injection flaw was found in the automation-controller. The controller relies on a single helper, sanitizejinja(), to reject user-supplied Jinja in several fields that are later handed to ansible-core for templating: the module arguments of ad-hoc commands, the username and privilege-escalation fields of Machine credentials, and inventory host names. That helper detects Jinja with two regular expressions whose negated character classes stop at the first interior '}' or '%' character. As a result, a Jinja expression that contains an inner brace — for example "{{ {} or lookup('pipe','id') }}" — is not matched and is accepted, even though it is fully valid Jinja that ansible-core will evaluate at task time. A low-privileged user can therefore inject Jinja that runs inside the execution environment. Two consequences are significant. First, the bypass defeats an administrator who has restricted the allowed ad-hoc modules to non-executing ones (such as ping) to provide "safe" ad-hoc access: a lookup('pipe', ...) embedded in the ping module's arguments executes an arbitrary shell command in the execution environment and returns its output in the job results. Second, the bypass lets a user who administers Machine credentials, but who cannot read another credential (such as a cloud or vault credential), place a lookup('env', ...) expression in a credential field; when both credentials are used together on a job template, the co-attached credential's secret is injected into the execution environment's process environment, templated into the attacker-controlled field, and surfaced in the job output — disclosing the secret across the credential access-control boundary. The underlying weakness is that the guard is an incomplete pattern-based blocklist rather than a real Jinja lexer or an unambiguous rejection of any '{{' or '{%' sequence.
— Red Hat
Affected Software
Event History
Frequently Asked Questions
What level of access does an attacker need?
A low-privileged user who can provide launch-time values in an affected field can exploit the issue. The supplied data indicates that no additional user interaction is required.
Which inputs should be prioritized when assessing exposure?
The affected launch-time inputs are ad-hoc command module_args, Machine credential username, become_method, and become_user fields, and inventory host names. These values can reach ansible-core templating in the execution environment.
Can module allowlisting prevent command execution through this issue?
No. The issue can enable arbitrary command execution in the execution environment while bypassing an administrator's AD_HOC_COMMANDS module allowlist.
What credential exposure is possible?
An attacker may disclose secrets associated with credentials they cannot normally read by templating injected environment variables from a co-attached credential. This crosses the credential access-control boundary.