Fedora Account System
Red Hat Associate
Red Hat Customer
A flaw was found in automation-controller (AWX). GET /api/controller/v2/hosts/ accepts a host_filter query parameter that HostList.get_queryset (awx/api/views/ __init__.py:1938-1944) parses with SmartFilter.query_from_string and intersects with the RBAC-filtered host queryset via `qs &= filter_qs`; that intersection restricts only which Host rows are returned, not which related rows the lookup's JOINs traverse. SmartFilter.BoolOperand (awx/main/utils/filters.py:151-170) validates the user-supplied lookup PATH only by calling FieldLookupBackend(). get_field_from_lookup(Host, k) and then executes Host.objects.filter(**{k: v}) directly, including __regex and __icontains lookups. FieldLookupBackend (django- ansible-base ansible_base/rest_filters/utils.py:9-69) rejects only fields in PASSWORD_FIELDS/encrypted_fields, fields marked __prevent_search__, and traversal loops -- it performs no authorization check on the rows the relation traversal reaches. JobEvent.event_data/stdout and AdHocCommandEvent.event_data/stdout (awx/main/models/events.py:215,253,695,705) are not wrapped in prevent_search(), unlike extra_vars, job_env, job_args and survey_passwords which are. Consequently a user with only the Read role on an inventory can submit host_filter values such as last_job__job_events__event_data__regex=<pattern>, job_events_as_primary_host__stdout__icontains=<substring>, or ad_hoc_command_events__event_data__regex=<pattern> and read the returned host count as a one-bit oracle. Since __regex is accepted, this allows efficient character-by- character extraction of the event_data/stdout of jobs and ad-hoc commands the caller is explicitly denied (HTTP 403) via the direct API, for any job that ever ran against a host in a readable inventory -- including jobs in other organizations when a host spans inventories across organizations. Job output routinely contains plaintext credentials, API tokens, command output and host facts. This is a horizontal privilege escalation from inventory-read to read-arbitrary-job-output. Discovered internally (pentest-aap); verified live on AAP 2.7 / automation- controller 4.8.1 (the forbidden job's playbook_uuid was extracted exactly); still present on devel. Upstream: github.com/ansible/awx (awx/api/views/__init__.py HostList.get_queryset; awx/main/utils/filters.py SmartFilter.BoolOperand; sensitive fields in awx/main/models/events.py) and github.com/ansible/django-ansible-base (ansible_base/rest_filters/utils.py get_fields_from_path).
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