[stable-2.20] Fix CVE-2026-11332 - prevent role requirements from configuring git (#87077)

* Fix CVE-2026-11332 - prevent role requirements from configuring git (#87070)

* Pass malformed role requirements as positional arguments to prevent arbitrary git configuration

* Add test coverage, checking for specific errors and that git clone is always followed by --

Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <wk.cvs.github@sydorenko.org.ua>
(cherry picked from commit edee59aa15)

* Fix ansible-galaxy-role test isolating stderr (#87085)

Follow up to #87070 to fix the test

Fix ansible-galaxy-role test isolating stder

Remove new feature to backport as-is

(cherry picked from commit bebae770d3)

---------

Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <wk.cvs.github@sydorenko.org.ua>
This commit is contained in:
Sloane Hertel
2026-06-09 11:23:40 -04:00
committed by GitHub
parent 6c3c0d5035
commit e67e842aa8
4 changed files with 56 additions and 1 deletions
@@ -0,0 +1,2 @@
security_fixes:
- ansible-galaxy install - Ensure role requirements are passed as positional arguments to :command:`git clone`. Previously, a malicious role author could inject arbitrary git configuration in role dependencies. (CVE-2026-11332)
+1 -1
View File
@@ -72,7 +72,7 @@ def scm_archive_resource(src, scm='git', name=None, version='HEAD', keep_scm_met
elif scm == 'hg':
clone_cmd.append('--insecure')
clone_cmd.extend([src, name])
clone_cmd.extend(['--', src, name])
run_scm_cmd(clone_cmd, tempdir)
@@ -0,0 +1,52 @@
- vars:
invalid_git_opts: '-ccore.sshCommand=sh -c "id > {{ remote_tmp_dir }}/role_exe"'
# use SSH protocol to test core.sshCommand is not configured
dummy_repo: git@github.com:ansible/nosuchrepo.git
block:
- name: Ensure git is installed
package:
name: git
when: ansible_distribution not in ["MacOSX", "Alpine"]
register: git_install
- name: Create invalid requirements file
copy:
dest: "{{ remote_tmp_dir }}/invalid-requirements.yml"
content: |
- src: {{ invalid_git_opts }}
scm: git
name: {{ dummy_repo }}
- src: {{ dummy_repo }}
scm: git
name: {{ invalid_git_opts }}
- name: Attempt to install invalid role requirements
command: ansible-galaxy install -r {{ remote_tmp_dir }}/invalid-requirements.yml --ignore-errors
register: result
environment:
ANSIBLE_NOCOLOR: True
ANSIBLE_FORCE_COLOR: False
- name: Validate git core.sshCommand did not run
stat:
path: "{{ remote_tmp_dir }}/role_exe"
register: stat_result
failed_when: stat_result.stat.exists
- name: Verify the invalid field is treated as a single positional argument (repo or dest)
assert:
that:
- stderr is search(error1)
- stderr is search(error2)
- (stderr | regex_findall("git clone") | length) == (stderr | regex_findall("git clone --") | length) == 2
vars:
stderr: "{{ result.stderr | regex_replace('\\n', ' ') }}"
error1: "repository '{{ invalid_git_opts }}' does not exist"
error2: "Cloning into '{{ invalid_git_opts }}'"
always:
- name: Uninstall git if it was installed
package:
name: git
state: absent
when: git_install is changed | default(false)
@@ -70,3 +70,4 @@
- import_tasks: dir-traversal.yml
- import_tasks: valid-role-symlinks.yml
- import_tasks: git-config-injection.yml