REDHAT-BUG-2490556: Ansible AAP Controller (HashiCorp Vault credential integration) vulnerability
A flaw was found in the AAP Controller's HashiCorp Vault credential integration. When a HashiCorp Vault Secret Lookup credential is configured with kubernetesrole authentication, the credential test endpoint (POST /api/controller/v2/credentials/{id}/test/) triggers the kubernetesauth() function which reads the controller pod's Kubernetes service account token from /var/run/secrets/kubernetes.io/serviceaccount/token and POSTs it as {"jwt": "<satoken>", "role": "<role>"} to the user-supplied vault URL. There is no validation or restriction on the vault URL target. An authenticated attacker with credential-creation privileges can set the vault URL to an attacker-controlled server and capture the SA token. The exfiltrated token (system:serviceaccount:ansible-automation-platform:automation-controller) has broad Kubernetes RBAC permissions including: full pod CRUD (get,list,watch,create,update,patch,delete) in both ansible-automation-job and ansible-automation-platform namespaces, and individual secret access (get,create,delete) in both namespaces. This allows the attacker to read database credentials, the Django SECRETKEY, and access all 31+ pods in the AAP platform namespace. In AAP Cloud (managed service) environments, this constitutes a tenant-to-infrastructure escape as the control plane is managed by Red Hat. The token has an approximately 1-year lifetime.
Upstream: https://github.com/ansible/awx (awxplugins/credentials/hashivault.py) Affected function: kubernetesauth() at hashivault.py:462-468 Reporter: Chris Meyers (internal — cmeyers) Tested against: platform.cus-0616.aws.ansiblecloud.com (AAP Cloud, ROSA)
Affected Software
Event History
Frequently Asked Questions
Who can exploit this issue?
An authenticated AAP Controller user who has privileges to create credentials can exploit it. They must be able to configure a HashiCorp Vault Secret Lookup credential using kubernetes_role authentication and invoke its credential test endpoint.
What does an attacker need to control?
The attacker needs an attacker-controlled server URL that can be supplied as the Vault URL. When the credential is tested, the controller sends its Kubernetes service account token to that URL in a POST request along with the configured role.
What access can the exposed token provide?
The token belongs to system:serviceaccount:ansible-automation-platform:automation-controller and has broad pod permissions in the ansible-automation-job and ansible-automation-platform namespaces. It also has get, create, and delete access to individual secrets in both namespaces, which can allow access to database credentials and the Django SECRET_KEY.
How can I determine whether exploitation may have occurred?
Review HashiCorp Vault Secret Lookup credentials configured with kubernetes_role authentication, especially those whose Vault URL is not a trusted Vault endpoint. Review use of POST /api/controller/v2/credentials/{id}/test/ and investigate outbound requests from the controller pod that sent service account JWTs to untrusted destinations.