Executive brief
libgit2 is a widely-used library for interacting with Git repositories, including cloning and updating code from remote servers. When configured to use the libssh2 SSH backend, the library fails to properly escape special characters in repository paths before executing them as shell commands on SSH servers. An attacker can exploit this by crafting a malicious repository URL containing shell metacharacters (such as single quotes or semicolons) that, when processed through submodule updates or direct clones, executes arbitrary commands on the victim's SSH account with their privileges.
Technical details
This is an OS command injection vulnerability (CWE-78) in the gen_proto() function of ssh_libssh2.c. The vulnerable code directly concatenates the repository path (url->path) into a shell command string without escaping special characters, then passes it to libssh2_channel_exec(). A path like /repo.git'; id; ' becomes the command git-upload-pack '/repo.git'; id; '', allowing the shell to interpret the injected commands. Attack vectors include direct clone/fetch operations with attacker-supplied URLs, or indirectly through malicious .gitmodules submodule entries (which can be hidden using include.path tricks). The fix, already applied to the ssh_exec backend, involves using git_str_puts_escaped() to properly escape quotes and special characters. Patched versions are libgit2 1.8.7 and 1.9.7 or later.
Affected products
- libgit2 libgit2 before 1.8.7 and 1.9.0 before 1.9.7 (when built with USE_SSH=libssh2)
Timeline
- 2026-08-11: disclosed
- 2026-08-15: patched: Patched versions: 1.8.7, 1.9.7