I got targeted: Trying to get your credentials via a git post-checkout hook

88 points by frankwiles 23 hours ago on lobsters | 32 comments

Sharparam | 11 hours ago

I feel like Git would benefit from a mechanism similar to direnv where you need to run an "allow" command first before hooks will execute.

[OP] frankwiles | 9 hours ago

Agreed!

Comment removed by author

toastal | 5 hours ago

Neither of which should be committed by users (examples are fine) so developers are free to set up or modify it to their content. One of my biggest peeves is being forced into someone else’s hooks or direnv setup which takes away my autonomy but can also leak into security. I write my own VCS hooks, but those are for me.

vifon | 4 hours ago

It's not possible to commit Git hooks into the repository. A helper script can generate these, but you'd need to run it first. Hooks are already purely local to a specific clone.

toastal | 4 hours ago

In theory, but I have seen so many folks commit something like Husky or pre-commit hooks & demand you set these up.

An even more devious attack is to ship a .git/config file with the core.fsmonitor option set to a malicious command. This command gets executed by many different git operations, including very basic ones like git status.

This is rather nasty because several other programs like to implicitly run git status, including IDEs, go build, and fancy shell prompt integrations that e.g. show the current branch. I disabled all of my git shell integrations and set GOFLAGS=-buildvcs=false after I learned about core.fsmonitor.

Note that git itself refuses to check out a .git directory from a remote repo so running git clone, git pull, etc. can never install a malicious config or hook, but if you install directory trees from any other source, like a tarball, a different VCS, or Dropbox (as in this article), you have to watch out for .git directories.

loldot | 10 hours ago

That is actually insane

0x2ba22e11 | 11 hours ago

I hate the entire existence of hooks for other reasons so this seems like a good push for me to configure git to never run them anywhere ever.

arialdo | 9 hours ago

Since I never use Git hooks, I have completely disabled them with:

git config --global core.hooksPath /dev/null

I like the idea; but it looks like a malicious repo can reenable hooks in its config file:

[core]
        hooksPath = .git/hooks

So I guess this global deactivation switch probably won't help against malicious repos?

arialdo | 8 hours ago

True. Mitigating this problem: core.hooksPath is not inherited from cloned repos.

An extremely cautionary move would be to never copy repos, always preferring cloning them.

0x2ba22e11 | 8 hours ago

Thanks

loldot | 12 hours ago

I have come to the conclusion that for interview coding tasks, I'll just either use the built-in vs code instance github (press . in any repository by the way) or in a VM. Between malicious third-party packages, git hooks, vs code config files etc, etc. I just consider everything project someone sends me as a malicious.

tinthedev | 15 hours ago

Never trust anything you download from a stranger still holds as true as ever. But yeah, hiding it within git hooks is pretty insidious. I appreciate the reminder that the repo can appear like "just text" but hide danger within.

I think we're about to have more and more of such exploits utilized within the git plumbing, until the class consciousness gets up to speed.

My tip for this kind of security check is to let a powerless LLM crawl every file and give me a report. Vulnerable to prompt injection, that's why powerless, but it mostly flags anything even remotely dodgy.

benoliver999 | 13 hours ago

I just did a job interview that had an at-home coding task. I said it felt like poor form to include .git in an emailed bundle so I wiped it, they agreed but also said they sometimes like seeing commits.

Never occurred to me it could be a major security risk!

vifon | 11 hours ago

If you mean a literal Git bundle generated with git bundle create, it should be safe to clone. The cloning will not check such files out. A plain zip archive or a tarball are fair game though.

steinuil | 10 hours ago

This is not the first attack I read about on here that involves git hooks. IMO the implementation is kind of insane and lends itself very well to this kind of attack. git basically treats the local .git directory as trusted probably because it believes that git repositories can only come from a clone (or init) operation, which has additional checks for hooks, but as we see here that is not always the case!

I don't like git hooks in general but I think a better trust model would look similar to direnv's. .envrc files must be explicitly allowed for them to run, and the hashes of the file and path of allowed .envrc files are stored in an allowlist in .local/share/direnv, which is (generally) outside of the bounds of any repo. It's not perfect: if the .envrc file contains use flake you won't get another prompt when the flake.nix file changes, but I think it'd be a reasonable improvement.

adrien | 15 hours ago

Can these hooks be secured? It looks like post-checkout could be on any repo hosted anywhere.

z3bra | 15 hours ago

This could be even worse. I assume git does a checkout after cloning a repository, this hook could be triggered right after a clone without your ability to review it.

Edit: I tried, and git refuses to checkout the file initially :

$ git clone bad-repo.got
Cloning into 'bad-repo'...
done.
error: invalid path '.git/hooks/post-checkout'
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'

So I assume that you're safe as long as you ALWAYS clone repositories with git, and don't retrieve the work tree from someone else (like the author was asked to).

Nothing within git (the repository format) prevents you from commiting a hook though, so it's up to the frontend to secure against it.

I also tried with got, and it refuses to checkout the file as well. No idea about jj or other git frontends.

tinthedev | 15 hours ago

The repo wasn't checked out - as the article says, downloaded via Dropbox.

z3bra | 10 hours ago

I know, I was wondering if the trick would also work when cloning a remote repository afresh. Turns out it doesn't (hopefully).

vifon | 12 hours ago

The ability to write files into .git/ on clone in some circumstances used to be a pretty serious Git vulnerability back in 2014. https://github.blog/security/supply-chain-security/vulnerability-announced-update-your-git-clients/

This specific one utilized case insensitive filesystems to store files such as .Git/config that to Git used to be distinct from .git/config, and hence allowed.

adrien | 8 hours ago

Thanks for trying. That's the setup I had in mind actually; I'm glad it doesn't work.

It's difficult for the format to do anything about this. You'd need to come up with a way of encoding a path which had no representation for paths starting with .git/.

This attack path has been known about for a long time. And git has refused to check out files at paths starting with ./git for as long as I remember.

There was a bug on windows years ago due to its case insensitive FS.

Generally treat any .git directory that git itself has not created as a live grenade.

stephenr | 12 hours ago

They then shared a Dropbox folder that had several folders of Markdown files.

This should have been the red flag. Not the .git directory or hooks in it.

azeemba | 7 hours ago

Why is that a red flag? If you are a contractor, getting a project layout/requirements like that seems reasonable

stephenr | 3 hours ago

Welp I blame reading it.. I dunno, without coffee. Maybe too much coffee?

I knew it was a git clone in a dropbox folder, and somehow my brain read that line (even when I quoted it in my comment) as "a folder that had several folders of Make files", and immediately I had visions of crazy people who know what Make is, but also put those Make files in Dropbox.

As the great man said, egg and my face, are in alignment.

agnishom | 7 hours ago

Sharing a Dropbox folder is a red flag?

wherewhy | 5 hours ago

Had something similar, though maybe less sneaky, happen to me. Wrote about it here: https://kraa.io/recruiter-scam

carlomonte | 12 hours ago

This is the price for having one universal tool and for having a monoculture based on it. Separation of concerns (earlier Unix) is still a sound engineering principle. Competition also helps. Without someone stealing their user base, Git will never touch such issues, for the sake of maintaining compatibility.

It might be that it was not the developers who turned their backs at Mercurial, Fossil and others, but the Hubs and the Labs. Maybe JJ shows us a way out of this situation.

mariusor | 7 hours ago

I don't think your post actually reflects the situation on the ground. If you only use git commands you're not exposing yourself to these types of attacks. The vector in the article is a git repository that the target was supposed to download verbatim via Dropbox (ie, with the .git/hooks folder included).

toastal | 5 hours ago

I’ve been kicking it primarily with Darcs (still holding out for Pijul tooling). I have been trying to build tooling to help VCS polyculture too which usually ends up being one of the primary reasons folks stick with Git.