BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Analyzing Git Clone Vulnerability

Analyzing Git Clone Vulnerability

This item in japanese

A new Git version, 2.30.2, fixes a security vulnerability in Git large file storage (LFS) and other clean/smudge filters affecting Git 2.15 and newer.

These updates address an issue where a specially crafted repository can execute code during a git clone on case-insensitive file systems which support symbolic links by abusing certain types of clean/smudge filters, like those configured by Git LFS.

Filed under CVE ID CVE-2021-21300, the vulnerability is of special concern for all users of Windows and macOS systems, which default to using case-insensitive file systems. It can however affect any system, including Linux, that uses a case-insensitive file system to checkout a Git repository.

Python programmer Foone Turing provided a detailed analysis of the vulnerability in a rather long and detailed Twitter thread. In a nutshell, the exploit requires two steps: getting the lstat cache into an invalid state and reordering checkout operations. One way to get the cache into an invalid state is by abusing a case-insensitive file system by causing a filename collision. Reordering checkout can be accomplished by using a clean/smudge filter with delayed checkout, of which Git LFS is the most notable example. These are the two ingredients that make the exploit possible.

A clean/smudge filter can be used when a file is required to have some local changes in order to be worked with but you do not want those changes to be committed back. An example of this could be converting line end formats or deployment-specific information that you need to override when working on a development system. Git LFS uses a clean/smudge filter to convert the URL to a large file, which is stored in your Git repo, into the file itself, which you want to be automatically downloaded from its storage location when you are working with the repository.

Using a clean/smudge filter is not enough to trigger the vulnerability, since applying a filter will not usually alter checkout order, unless delayed checkout is used, that is, which is exactly what Git LFS enables to prevent a very large file download from pausing checking out the rest of the files in the repo while the download is in progress. As a consequence of this, any large files will be checked out after other files that Git can process without waiting for the download to complete, without respecting the real checkout order.

With this information in mind, we can try to understand the following code, which provides a demo exploit for the vulnerability:

  #!/bin/sh

  git init delayed-checkout &&
  (
  	cd delayed-checkout &&
  	echo "A/post-checkout filter=lfs diff=lfs merge=lfs" \
  		>.gitattributes &&
  	mkdir A &&
  	printf '#!/bin/sh\n\necho PWNED >&2\n' >A/post-checkout &&
  	chmod +x A/post-checkout &&
  	>A/a &&
  	>A/b &&
  	git add -A &&
  	rm -rf A &&
  	ln -s .git/hooks a &&
  	git add a &&
  	git commit -m initial
  ) &&
  git clone delayed-checkout cloned

As you can see, a malicious A file is first added to the repo, then it is removed and replaced through a non-malicious a symbolic link. Those two files will never cause a collision on a case-sensitive file system, nor will there be a collision if Git is able to replay all operations in the same order. This is the case because you can never create a file system name collision with a sequence of operations, since the file system will prevent you from doing so and the Git cache will remain sound. But, by reordering checkout, you could make the A exploit land in Git cache and thus run during the clone.

It is worth noting that the exploit is not limited exclusively to case-insensitive file systems and to the use of Git LFS. It can be triggered in any case where there is a file system name clash and a clean/smudge filter is used with delayed checkout.

In a short announcement, GitHub stated they are not affected by the vulnerability:

GitHub itself is not vulnerable to this attack. We do not store checked out copies of repositories on our servers, except for GitHub Pages, which does not use any clean/smudge filters.

According to GitHub, if upgrading Git to version 2.30.2 is not an option, users can mitigate their risk in three ways. First, they can disable support for symbolic links setting the core.symlinks configuration option to false. Alternatively, they can disable process filters. As a last resort, users can avoid cloning untrusted repositories.

Rate this Article

Adoption
Style

BT