Bug 2527211 (CVE-2026-84718) - CVE-2026-84718 automation-controller: automation-controller: client IP spoofing in audit/access logs via unrestricted X-Forwarded-For trust
Summary: CVE-2026-84718 automation-controller: automation-controller: client IP spoofi...
Keywords:
Status: NEW
Alias: CVE-2026-84718
Deadline: 2026-10-01
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Product Security
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-09-02 01:21 UTC by Thomas Eagle
Modified: 2026-09-23 21:08 UTC (History)
8 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2026:71113 0 None None None 2026-09-23 20:51:34 UTC
Red Hat Product Errata RHSA-2026:71114 0 None None None 2026-09-23 21:08:08 UTC

Description Thomas Eagle 2026-09-02 01:21:03 UTC
A flaw was found in the Ansible Automation Platform automation-controller request handling. The
shipped production settings define REMOTE_HOST_HEADERS=['HTTP_X_FORWARDED_FOR'] and
PROXY_IP_ALLOWED_LIST=[] (empty). In APIView.initialize_request (awx/api/generics.py:199-201),
client-supplied REMOTE_HOST_HEADERS are stripped only when PROXY_IP_ALLOWED_LIST is non-empty
and the request did not arrive through a listed proxy; with the empty shipped allow-list this
guard is skipped and the X-Forwarded-For header is never stripped. When the client IP is
resolved via get_remote_host()/get_remote_hosts() (django-ansible-base
ansible_base/lib/utils/requests.py), the function reads REMOTE_HOST_HEADERS in order and
returns the first (leftmost) X-Forwarded-For entry. Because the deployment fronts Controller
with Envoy, which by default appends (rather than replaces) the real client IP to the incoming
X-Forwarded-For header, an attacker-supplied leftmost value survives to the application and is
chosen as the client IP. That spoofed value is written into the Controller's audit/access
logging, including the login audit message ("User <username> logged in from <ip>") and the API
4xx error log's remote_addr field (API_400_ERROR_LOG_FORMAT). An attacker can therefore forge
the source IP attributed to API actions in Controller logs and any downstream SIEM keyed on
client IP. Unauthenticated failed-login and error log entries can likewise be attributed to
arbitrary IPs. A secure mechanism already exists but is not enabled by default: when a valid
HTTP_X_TRUSTED_PROXY shared-secret header is present, get_remote_hosts prefers the trusted
last/rightmost X-Forwarded-For entry (the value Envoy appends) and honors
x-envoy-external-address. The flaw affects only audit/forensic integrity and does not grant
additional access.

    Upstream: https://github.com/ansible/tower (awx) and
              https://github.com/ansible/django-ansible-base (get_remote_host[s])
    Affected file: awx/api/generics.py:199-201 (guard), :119 and :246-265 (sinks);
                   awx/settings/production_defaults.py:23; awx/settings/defaults.py:166;
                   ansible_base/lib/utils/requests.py:14-16,38-42,65-66

Comment 2 Jon Orris 2026-09-23 20:51:32 UTC
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

Comment 3 Jon Orris 2026-09-23 21:08:07 UTC
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


Note You need to log in before you can comment on or make changes to this bug.