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.
Damn! I wouldn't have expected it to be so dangerous to clone a repository and perform basic operations on it. I really thought that this type of flow would have been safe.
As I said in my comment, cloning a repo cannot install malicious config. It's the other ways of installing directory trees that you have to be wary of.
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.
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.
Cloning a repo is in fact the only safe way to get a repo from an untrusted source. Specifically, the Git project considers it a vulnerability if cloning a repo pwns you; they do not consider it a vulnerability if installing a repo a different way pwns you.
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.
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!
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.
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.
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.
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.
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.
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.
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.
I immediately alerted Dropbox and Vercel’s security teams so they can hopefully take these accounts down before they snag someone. Sadly, they also were impersonating an unspecting development shop owner as part of the ruse.
Is there a reason not to involve law enforcement in this case? Seems like the author could have been significantly harmed if they weren't already aware of this attack vector.
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.
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).
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.
agwa | 22 days ago
An even more devious attack is to ship a
.git/configfile with thecore.fsmonitoroption set to a malicious command. This command gets executed by many different git operations, including very basic ones likegit 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 setGOFLAGS=-buildvcs=falseafter I learned aboutcore.fsmonitor.Note that git itself refuses to check out a
.gitdirectory from a remote repo so runninggit 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.gitdirectories.loldot | 22 days ago
That is actually insane
SamRW | 21 days ago
Damn! I wouldn't have expected it to be so dangerous to clone a repository and perform basic operations on it. I really thought that this type of flow would have been safe.
agwa | 21 days ago
As I said in my comment, cloning a repo cannot install malicious config. It's the other ways of installing directory trees that you have to be wary of.
Sharparam | 22 days 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 | 22 days ago
Agreed!
toastal | 21 days 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 | 21 days 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 | 21 days ago
In theory, but I have seen so many folks commit something like Husky or pre-commit hooks & demand you set these up.
fanf | 22 days ago
0x2ba22e11 | 22 days 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 | 22 days ago
Since I never use Git hooks, I have completely disabled them with:
oger | 22 days ago
I like the idea; but it looks like a malicious repo can reenable hooks in its config file:
So I guess this global deactivation switch probably won't help against malicious repos?
arialdo | 22 days ago
True. Mitigating this problem:
core.hooksPathis not inherited from cloned repos.An extremely cautionary move would be to never copy repos, always preferring cloning them.
agwa | 21 days ago
Cloning a repo is in fact the only safe way to get a repo from an untrusted source. Specifically, the Git project considers it a vulnerability if cloning a repo pwns you; they do not consider it a vulnerability if installing a repo a different way pwns you.
0x2ba22e11 | 22 days ago
Thanks
loldot | 22 days 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.
benoliver999 | 22 days ago
I just did a job interview that had an at-home coding task. I said it felt like poor form to include
.gitin 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 | 22 days 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.tinthedev | 22 days 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.
steinuil | 22 days 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
.gitdirectory as trusted probably because it believes that git repositories can only come from aclone(orinit) 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.
.envrcfiles must be explicitly allowed for them to run, and the hashes of the file and path of allowed.envrcfiles 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.envrcfile containsuse flakeyou won't get another prompt when theflake.nixfile changes, but I think it'd be a reasonable improvement.ghthor | 21 days ago
There is a feature on direnv main for this, marking files as changes require reallow. But they haven’t cut a new release since it was merged.
stephenr | 22 days ago
This should have been the red flag. Not the .git directory or hooks in it.
azeemba | 21 days ago
Why is that a red flag? If you are a contractor, getting a project layout/requirements like that seems reasonable
stephenr | 21 days 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 | 21 days ago
Sharing a Dropbox folder is a red flag?
adrien | 22 days ago
Can these hooks be secured? It looks like post-checkout could be on any repo hosted anywhere.
z3bra | 22 days 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 :
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 aboutjjor other git frontends.tinthedev | 22 days ago
The repo wasn't checked out - as the article says, downloaded via Dropbox.
z3bra | 22 days 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 | 22 days 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/configthat to Git used to be distinct from.git/config, and hence allowed.atk | 21 days ago
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
./gitfor 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.
adrien | 22 days ago
Thanks for trying. That's the setup I had in mind actually; I'm glad it doesn't work.
wherewhy | 21 days ago
Had something similar, though maybe less sneaky, happen to me. Wrote about it here: https://kraa.io/recruiter-scam
junot | 21 days ago
Is there a reason not to involve law enforcement in this case? Seems like the author could have been significantly harmed if they weren't already aware of this attack vector.
carlomonte | 22 days 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 | 21 days 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 | 21 days 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.