CVE-2026-89091 Overview
CVE-2026-89091 is a symlink-based path traversal vulnerability in ansible-core that affects the ansible-galaxy collection install command. The archive extractor validates member paths using lexical normalization through os.path.abspath instead of resolving symbolic links with os.path.realpath. It also skips containment checks on symlink-typed directory members before creating them. An attacker who convinces a victim to install a malicious collection can write files outside the destination directory. This bypasses the fix issued for CVE-2020-10691 and can lead to arbitrary code execution on the Ansible control node.
Critical Impact
A crafted collection tarball can overwrite arbitrary files with the privileges of the user running ansible-galaxy, enabling code execution on the control node.
Affected Products
- ansible-core (versions distributed through Red Hat and upstream channels)
- Red Hat Ansible Automation Platform components bundling ansible-core
- Any environment using ansible-galaxy collection install to retrieve third-party collections
Discovery Timeline
- 2026-10-08 - CVE-2026-89091 published to NVD
- 2026-10-09 - Last updated in NVD database
Technical Details for CVE-2026-89091
Vulnerability Analysis
The flaw is classified under [CWE-59] Improper Link Resolution Before File Access, commonly known as a symlink attack. During collection installation, ansible-galaxy extracts a tarball retrieved from Galaxy or a user-supplied source. The extractor iterates archive members and attempts to confirm each destination path falls within the installation directory. That confirmation uses os.path.abspath, which performs string-level normalization only. It does not follow symbolic links present on disk.
Because symlink-typed directory members are created without a containment check, an attacker can place a symlink entry early in the archive that points outside the install root. A later file member written through that symlinked directory lands at an attacker-chosen filesystem location. The result is an arbitrary file write primitive that executes with the privileges of the invoking user. Exploitation requires user interaction, as the victim must trigger the install, but no authentication to the target host is required.
Root Cause
The root cause is the use of lexical path normalization rather than canonical path resolution. os.path.abspath collapses .. segments and joins the path with the current working directory, yet it never consults the filesystem. os.path.realpath resolves symlinks and reveals the true target. By mixing symlink directory creation with lexical checks, the extractor can be tricked into treating an out-of-tree path as safe.
Attack Vector
An attacker publishes or delivers a crafted collection tarball. The archive chains a symlink directory member pointing outside the destination, followed by a file member written through that symlink. When the victim runs ansible-galaxy collection install, the file lands at an attacker-chosen location such as ~/.bashrc, an Ansible plugin directory, or a cron entry. Overwriting any of these yields code execution on the control node.
No verified public exploit code is available at this time. Refer to the Red Hat CVE-2026-89091 Advisory and the Red Hat Bug Report #2531646 for technical details.
Stop Remote Code Execution Before It Runs
Singularity™ Endpoint detects and blocks exploit attempts at machine speed, including zero-days and novel attack techniques.
Stop Exploit AttemptsDetection Methods for CVE-2026-89091
Indicators of Compromise
- Unexpected files or modifications under user home directories, ~/.ansible/, /etc/, or Ansible plugin paths shortly after a ansible-galaxy collection install operation.
- Collection tarballs containing symlink entries whose targets reference .. or absolute paths outside the collection root.
- New or modified shell startup files, cron jobs, or systemd units on Ansible control nodes with no corresponding change ticket.
Detection Strategies
- Inspect downloaded collection archives with tar -tvf before installation to flag symlink members pointing outside the archive tree.
- Audit shell history and process telemetry for ansible-galaxy collection install invocations against untrusted sources.
- Compare file integrity baselines on control nodes against post-install state to identify writes outside expected collection directories.
Monitoring Recommendations
- Enable filesystem auditing on ~/.ansible/collections/ and system directories writable by Ansible operators.
- Forward ansible-galaxy command execution and child-process telemetry to a central log store for correlation.
- Alert on symlink creation events originating from Python interpreters running ansible-galaxy.
How to Mitigate CVE-2026-89091
Immediate Actions Required
- Upgrade ansible-core to the fixed version published in the Red Hat CVE-2026-89091 Advisory as soon as it is available for your distribution.
- Restrict ansible-galaxy collection install to vetted sources and signed collections only.
- Audit control nodes for recent installations from untrusted Galaxy namespaces or ad-hoc tarballs.
Patch Information
Red Hat tracks the fix under the advisory linked above and the associated Red Hat Bug Report #2531646. Apply vendor-supplied ansible-core updates on all control nodes and automation controllers. For environments using upstream ansible-core from PyPI, upgrade to the patched release once published and rebuild any execution environments that bundle the library.
Workarounds
- Install collections only from trusted, signed sources and pin collection versions in requirements.yml.
- Run ansible-galaxy collection install under a dedicated unprivileged account with no write access to system directories or sensitive dotfiles.
- Manually inspect third-party collection tarballs for symlink members before extraction using tar -tvf <archive>.
# Configuration example: inspect a collection archive for suspicious symlinks
tar -tvf untrusted-collection.tar.gz | awk '$1 ~ /^l/ {print}'
# Run ansible-galaxy as a non-privileged user with an isolated collections path
sudo -u ansible-restricted \
ANSIBLE_COLLECTIONS_PATH=/opt/ansible/sandbox/collections \
ansible-galaxy collection install -r requirements.yml
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

