Fedora Account System
Red Hat Associate
Red Hat Customer
A flaw was found in Ansible Automation Platform's automation-controller. Custom Credential Types let an author define injectors.env (environment variables set in the execution environment when a credential of that type is attached to a job) and injectors.file (files rendered into the execution environment whose path is exposed to other injectors as {{ tower.filename }}). The env-variable names are validated only by a deny-list: CredentialTypeInjectorField.validate_env_var_allowed (awx/main/fields.py:689-701) rejects names beginning with "ANSIBLE_" and names present in the ENV_BLOCKLIST frozenset (awx/main/constants.py:48-70). The stated purpose of this control is to stop injectors from hijacking the runner process (it blocks PATH, PYTHONPATH, VIRTUAL_ENV and all ANSIBLE_* configuration variables). The deny-list is incomplete: it does not include BASH_ENV, ENV, LD_PRELOAD, LD_LIBRARY_PATH, LD_AUDIT, PYTHONSTARTUP, PYTHONWARNINGS, GIT_SSH_COMMAND, PERL5OPT, or similar loader/ process-hijacking variables, so those names pass validation. An attacker can therefore define a credential type whose file injector writes a shell script and whose env injector sets BASH_ENV to {{ tower.filename }}. Every non-interactive bash process spawned during a job (Ansible modules shell out constantly) then sources and executes the attacker's script, yielding arbitrary code execution inside the execution-environment container — independent of the playbook content — for any job that attaches a credential of the malicious type, with access to the secrets of all co-attached credentials in the same job environment and to any inventory host the job can reach. The same weak check is repeated at the runtime injection sink (awx_plugins.interfaces _temporary_private_inject_api.py, which re-checks only ENV_BLOCKLIST), so the fix must be applied in both places. Creating a custom credential type requires Controller superuser (CredentialTypeAccess inherits BaseAccess), so this is primarily a defense-in-depth bypass of a control whose explicit purpose is to constrain exactly this behavior; however, an organization-level Credential Admin (not a superuser) can weaponize an already-existing malicious custom type, and in Gateway-managed AAP 2.5+ the platform-admin role is explicitly not host/EE root, so code execution in the execution environment via a configuration API crosses a real trust boundary. Upstream: https://github.com/ansible/tower (private) / awx_plugins.interfaces Affected files: awx/main/fields.py:689-701; awx/main/constants.py:48-70; awx_plugins/interfaces/_temporary_private_inject_api.py:263-288
This issue has been addressed in the following products: Red Hat Ansible Automation Platform 2.6 for RHEL 10 Red Hat Ansible Automation Platform 2.6 for RHEL 9 Via RHSA-2026:71113 https://access.redhat.com/errata/RHSA-2026:71113
This issue has been addressed in the following products: Red Hat Ansible Automation Platform 2.5 for RHEL 9 Red Hat Ansible Automation Platform 2.5 for RHEL 8 Via RHSA-2026:71114 https://access.redhat.com/errata/RHSA-2026:71114