Remediating the May 2018 Git Security Vulnerability
May 29, 2018
The Git community has disclosed an industry-wide security vulnerability in Git that can lead to arbitrary code execution when a user operates in a malicious repository. This vulnerability has been assigned CVE 2018-11235 by Mitre, the organization that assigns unique numbers to track security vulnerabilities in software.
Git 2.17.1 was released today and includes this fix. Git for Windows 2.17.1 (2) has been released that includes this fix. The Visual Studio Team Services (VSTS) team takes security issues very seriously, and we encourage all users to update their Git clients as soon as possible to fix this vulnerability. To further protect you, our team has blocked these types of malicious repositories from being pushed to VSTS. This will ensure that we cannot be used as a vector for transmitting maliciously crafted repositories to users who have not yet patched their clients for this vulnerability.
If you’re using Git for Windows, please download the latest version — 2.17.1(2) — from https://gitforwindows.org/. Visual Studio 2017 users should install updates; both Visual Studio 15.7.3 and 15.0.14 include updates to fix this vulnerability. If you are using other Git clients, please contact your vendor to understand if you need to upgrade and how to do that.
What is the Git vulnerability?
A remote repository may contain a definition for a submodule, and also bundle that submodule’s repository data, checked in to the parent repository as a folder. When recursively cloning this repository, git will first checkout the parent repository into the working directory, then prepare to clone the submodule. It will then realize that it doesn’t need to do the clone – the submodule’s repository already exists on disk; since it was checked in to the parent, it was written to the working directory when it was checked out. Therefore git can skip the fetch and simply check out the submodule using the repository that’s on disk.
The problem is that when you git clone a repository, there is some important configuration that you don’t get from the server. This includes the contents of the .git/config file, and things like hooks, which are scripts that will be run at certain points within the git workflow. For example, the post-checkout hook will be run anytime git checks files out into the working directory.
This configuration is not cloned from the remote server because that would open a dangerous vulnerability: that a remote server could provide you code that you would then execute on your computer.
Unfortunately, with this submodule configuration vulnerability, that’s exactly what happens. Since the submodule’s repository is checked in to the parent repository, it’s never actually cloned. The submodule repository can therefore actually have a hook already configured. If when you recursively cloned this carefully crafted malicious parent repository, it will first check out the parent, then read the submodule’s checked-in repository in order to write the submodule to the working directory, and finally it will execute any post-checkout hooks that are configured in the submodule’s checked-in repository.
Solution
The solution to this problem is quite simple and effective: submodule’s folder names are now examined more closely by Git clients. They can no longer contain .. as a path segment, and they cannot be symbolic links, so they must be within the .git repository folder, and not in the actual repository’s working directory.
How about for Mac? Looks like you can only get 2.17.0?
Good question – for macOS, I recommend that people keep up to date using Homebrew. (It has git 2.17.1 as of a few hours ago.) Instructions are at https://www.edwardthomson.com/blog/upgrading_git_for_cve2018_11235.html
`port selfupdate; port upgrade git` worked for me
You are your team are doing a marvelous job, Keep up and good work and big thanks to the macOS answer!
Relying on git clone –recursive was never a good idea, because a lot of users just “git clone” before reading README or thinking about dependencies or submodules.
Downloading submodules should be handled in the repo (`make deps` or something)
So are we safe if we dont use submodules?
Yes. If you don’t run `git clone –recursive` or otherwise manipulate submodules, then you are safe.
brew upgrade; brew install git
How about security patches for TFS?
TFS 2018 Update 3 will block these repositories.
How about TFS 2017 on-premise? Is there any patch for TFS 2017 which blocks these types of malicious repositories from being pushed to TFS?
How about TFS 2017 on-premise? Is there any patch for TFS 2017 has blocked these types of malicious repositories from being pushed to TFS?
Team Foundation Server 2018 Update 3 will include these blocks, for completeness. Since Team Foundation Server is installed on-premises, within your organization, and requires authentication both to read and write the repository, it’s not an effective vector to propagate this vulnerability while clients are getting updated. We would encourage you to make sure that the clients in your organization are updated.
Does this vulnerability affect all versions of Git before 2.17.1?
thanks
I have a Windows client and I run my own Git server. I just upgraded the client to 2.17.1 and the server to the same. During a push, I now get:
remote: error: cannot lock ref ‘HEAD’: Unable to create ‘/opt/git-repos/fms/v2.git/./HEAD.lock’: Permission denied
To ssh://craigonmars.com/opt/git-repos/fms/v2.git
! [remote rejected] master -> master (failed to update ref)
error: failed to push some refs to ‘[[ssh url to my remote repo]]’
I assume this is because of the new protection? However, I cloned a fresh repo on my Windows box and got the same when I pushed. Is there something I need to update on the bare repo on the server or is the error about something else?
I am using the Windows client and I run my own Git server on Ubuntu. Today, I upgraded both client and server to 2.17.1 (my Git Bash actually says 2.17.1.windows.2) but now I cannot do a push. Instead, I get:
remote: error: cannot lock ref ‘HEAD’: Unable to create ‘/opt/git-repos/fms/v2.git/./HEAD.lock’: Permission denied
To ssh://craigonmars.com/opt/git-repos/fms/v2.git
! [remote rejected] master -> master (failed to update ref)
error: failed to push some refs to ‘[[my git repo url]]’
I assume this is part of the fix, preventing older clients from pushing non-compliant configs to the server? I looked for “..” in the client’s config and didn’t find it. (I am not aware of any symbolic links.) I did a fresh clone but push failed there too.
Please advise.