Fedora Account System
Red Hat Associate
Red Hat Customer
A flaw was found in automation-controller (AWX). Project.scm_branch (awx/main/models/credential path awx/main/models/projects.py:98-111, a CharField with no validators) and scm_refspec are accepted as free text with no rejection of a leading dash (no validate_scm_branch/validate_scm_refspec and no leading-dash guard anywhere in awx/api/serializers.py, awx/main, or awx/playbooks). During project sync, RunProjectUpdate.build_extra_vars_file (awx/main/tasks/jobs.py:1481-1518) copies scm_branch (:1486/:1508) and scm_refspec (:1517-1518) verbatim into the project-update extra_vars, and awx/playbooks/project_update.yml (`- hosts: localhost`, `connection: local`, :28-30) passes them to the ansible.builtin.git module as `version: "{{ scm_branch | quote }}"` (:50) and `refspec: "{{ scm_refspec | default(omit) }}"` (:51). The git module's switch_version() builds `[/usr/bin/git, checkout, --force, <version>]` with no `--` end-of-options sentinel (upstream lib/ansible/modules/git.py), so a value beginning with `--` is parsed by git as an option flag. The `| quote` filter is ansible's shlex.quote and does NOT defend against this: an all-shell-safe string such as `--pathspec-from-file=/etc/passwd` is returned unchanged (matching the live proof, whose command line shows no quotes). Setting scm_branch to `--pathspec-from-file=/var/run/secrets/kubernetes.io/serviceaccount/token` makes git read the file line-by-line as pathspecs and echo each line on stderr as `error: pathspec '<line>' did not match any file(s) known to git`; ansible-runner captures stderr into the job event stream, returned via GET /api/controller/v2/project_updates/{id}/stdout/?format=txt — an arbitrary-file-read oracle on the sync host. Because project_update.yml runs on localhost and, on the tested OpenShift Operator deployment, that host is the automation-controller-task control-plane pod (confirmed: the leaked token's pod name matches a control node in /api/controller/v2/ping/), the read reaches control-plane secrets: the system:serviceaccount:ansible-automation-platform:automation-controller JWT (pod/secret CRUD in the AAP namespace -> full platform takeover), /etc/tower/SECRET_KEY (offline decryption of every stored Credential), and /etc/tower/conf.d/*.py (PostgreSQL credentials). Any user able to create or edit a project (Organization project_admin, or Project Admin on a single project) can trigger this on project create/edit auto-sync; system administrator is not required, and any org's admin reads secrets governing all tenants on the control plane. scm_refspec (fed to `git fetch`, no quote at all) is a second option-injection sink to fix together. On deployments where project updates run in an isolated execution environment without control-plane secrets, the primitive is limited to that context. Discovered internally (pentest-aap); verified live on AAP 2.7 / automation-controller 4.8.1; still present on devel (fix prepared, not merged) Upstream: github.com/ansible/awx (awx/main/models/projects.py scm_branch/scm_refspec; awx/api/serializers.py Project serializers; awx/main/tasks/jobs.py RunProjectUpdate.build_extra_vars_file; awx/playbooks/project_update.yml) and github.com/ansible/ansible (ansible.builtin.git switch_version -- add `--`).
This issue has been addressed in the following products: Red Hat Ansible Automation Platform 2.4 for RHEL 8 Red Hat Ansible Automation Platform 2.4 for RHEL 9 Via RHSA-2026:71115 https://access.redhat.com/errata/RHSA-2026:71115
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