* Git 2.45.1 - What is the right way to clone with global hooks disabled? @ 2024-05-15 15:53 Brooke Kuhlmann 2024-05-15 22:25 ` brian m. carlson 2024-05-16 12:13 ` Johannes Schindelin 0 siblings, 2 replies; 7+ messages in thread From: Brooke Kuhlmann @ 2024-05-15 15:53 UTC (permalink / raw) To: git Hello. 👋 With the release of Git 2.45.1, I can no longer do this when cloning trusted repositories (my own) for build and deployment purposes: git clone --config core.hooksPath=/dev/null https://github.com/bkuhlmann/infusible I have automation in place where I want my global Git Hooks to be ignored when cloning like this. The solution is to do this: GIT_CLONE_PROTECTION_ACTIVE=false git clone --config core.hooksPath=/dev/null https://github.com/bkuhlmann/infusible ...but is there a better, more secure, way to clone a repository while ignoring any global Git Hooks from firing without a lot of effort? Thanks. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Git 2.45.1 - What is the right way to clone with global hooks disabled? 2024-05-15 15:53 Git 2.45.1 - What is the right way to clone with global hooks disabled? Brooke Kuhlmann @ 2024-05-15 22:25 ` brian m. carlson 2024-05-16 14:59 ` Junio C Hamano 2024-05-16 12:13 ` Johannes Schindelin 1 sibling, 1 reply; 7+ messages in thread From: brian m. carlson @ 2024-05-15 22:25 UTC (permalink / raw) To: Brooke Kuhlmann; +Cc: git [-- Attachment #1: Type: text/plain, Size: 1853 bytes --] On 2024-05-15 at 15:53:26, Brooke Kuhlmann wrote: > Hello. 👋 > > With the release of Git 2.45.1, I can no longer do this when cloning trusted repositories (my own) for build and deployment purposes: > > git clone --config core.hooksPath=/dev/null https://github.com/bkuhlmann/infusible > > I have automation in place where I want my global Git Hooks to be ignored when cloning like this. The solution is to do this: > > GIT_CLONE_PROTECTION_ACTIVE=false git clone --config core.hooksPath=/dev/null https://github.com/bkuhlmann/infusible > > ...but is there a better, more secure, way to clone a repository while ignoring any global Git Hooks from firing without a lot of effort? I think the solution you have is the best one for 2.45.1 right now. The patches which introduced this change also introduced a regression with Git LFS, and I've proposed two revert patches, which would also restore the old behaviour for you. My reverts are somewhat controversial and there's been two different approaches proposed, but I don't believe they will solve your problem, so if the reverts are not merged, then I think the solution you have is the best one for now. It's possible someone could send a different patch to address your use case, but I don't know of any plans to do so at the moment. I didn't see my patches in seen earlier, but it's possible that Junio has just been busy with other things and may pick them up (or not) in the future. If they're not adopted, while I'm not personally planning to send patches for your use case, I do think it's a valuable and useful use case for us to have and consider, so I hope someone does send a patch separately. [0] https://lore.kernel.org/git/ZkO-b6Nswrn9H7Ed@tapette.crustytoothpaste.net/T/ -- brian m. carlson (they/them or he/him) Toronto, Ontario, CA [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 262 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Git 2.45.1 - What is the right way to clone with global hooks disabled? 2024-05-15 22:25 ` brian m. carlson @ 2024-05-16 14:59 ` Junio C Hamano 0 siblings, 0 replies; 7+ messages in thread From: Junio C Hamano @ 2024-05-16 14:59 UTC (permalink / raw) To: brian m. carlson; +Cc: Brooke Kuhlmann, git "brian m. carlson" <sandals@crustytoothpaste.net> writes: > I didn't see my patches in seen earlier, but it's possible that Junio > has just been busy with other things and may pick them up (or not) in > the future. I knew about this message, and addressed your half of the "hooks" topic in my response to Dscho's proposed patch to the other half of the "hooks" topic, but I didn't realize Dscho's message did not Cc you. It should appear at https://lore.kernel.org/git/xmqq4jaxvm8z.fsf@gitster.g/ by the time I send this message. Thanks. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Git 2.45.1 - What is the right way to clone with global hooks disabled? 2024-05-15 15:53 Git 2.45.1 - What is the right way to clone with global hooks disabled? Brooke Kuhlmann 2024-05-15 22:25 ` brian m. carlson @ 2024-05-16 12:13 ` Johannes Schindelin 2024-05-16 13:05 ` Brooke Kuhlmann 2024-05-16 14:56 ` Junio C Hamano 1 sibling, 2 replies; 7+ messages in thread From: Johannes Schindelin @ 2024-05-16 12:13 UTC (permalink / raw) To: Brooke Kuhlmann; +Cc: git Hi Brooke, On Wed, 15 May 2024, Brooke Kuhlmann wrote: > With the release of Git 2.45.1, I can no longer do this when cloning > trusted repositories (my own) for build and deployment purposes: > > git clone --config core.hooksPath=/dev/null https://github.com/bkuhlmann/infusible Ah, that's a clever trick. The clone protections try to prevent overriding the `core.hooksPath` with a valid (but not intended by the user) path. What you are doing is to specifically turn hooks off *1*. I plan on sending out a patch series later either today or tomorrow to address a couple of regressions introduced by v2.45.1, and this patch would address your specific scenario: -- snip -- diff --git a/config.c b/config.c index 85b37f2ee09..380f7777a6e 100644 --- a/config.c +++ b/config.c @@ -1527,6 +1527,7 @@ static int git_default_core_config(const char *var, const char *value, void *cb) if (!strcmp(var, "core.hookspath")) { if (current_config_scope() == CONFIG_SCOPE_LOCAL && + (!value || (*value && strcmp(value, "/dev/null"))) && git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0)) die(_("active `core.hooksPath` found in the local " "repository config:\n\t%s\nFor security " diff --git a/t/t1350-config-hooks-path.sh b/t/t1350-config-hooks-path.sh index f6dc83e2aab..1eae346a6e3 100755 --- a/t/t1350-config-hooks-path.sh +++ b/t/t1350-config-hooks-path.sh @@ -41,4 +41,8 @@ test_expect_success 'git rev-parse --git-path hooks' ' test .git/custom-hooks/abc = "$(cat actual)" ' +test_expect_success 'core.hooksPath=/dev/null' ' + git clone -c core.hooksPath=/dev/null . no-templates +' + test_done > I have automation in place where I want my global Git Hooks to be > ignored when cloning like this. The solution is to do this: > > GIT_CLONE_PROTECTION_ACTIVE=false git clone --config core.hooksPath=/dev/null https://github.com/bkuhlmann/infusible > > ...but is there a better, more secure, way to clone a repository while > ignoring any global Git Hooks from firing without a lot of effort? That is certainly a good work-around for now. Thank you for the report! I hope that we can address your use case in v2.45.2, hopefully soon. Thanks, Johannes ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: Git 2.45.1 - What is the right way to clone with global hooks disabled? 2024-05-16 12:13 ` Johannes Schindelin @ 2024-05-16 13:05 ` Brooke Kuhlmann 2024-05-16 14:56 ` Junio C Hamano 1 sibling, 0 replies; 7+ messages in thread From: Brooke Kuhlmann @ 2024-05-16 13:05 UTC (permalink / raw) To: brian m. carlson, Johannes Schindelin; +Cc: git Hey Brian and Johannes, thanks for your feedback. 🙇🏻♂️ Brian, true, the Git LFS issues don't necessarily help me. Johannes, yes, your patch would definitely be of great help to me. Thanks for doing that! > On May 16, 2024, at 6:13 AM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > > Hi Brooke, > > On Wed, 15 May 2024, Brooke Kuhlmann wrote: > >> With the release of Git 2.45.1, I can no longer do this when cloning >> trusted repositories (my own) for build and deployment purposes: >> >> git clone --config core.hooksPath=/dev/null https://github.com/bkuhlmann/infusible > > Ah, that's a clever trick. The clone protections try to prevent overriding > the `core.hooksPath` with a valid (but not intended by the user) path. > What you are doing is to specifically turn hooks off *1*. > > I plan on sending out a patch series later either today or tomorrow to > address a couple of regressions introduced by v2.45.1, and this patch > would address your specific scenario: > > -- snip -- > diff --git a/config.c b/config.c > index 85b37f2ee09..380f7777a6e 100644 > --- a/config.c > +++ b/config.c > @@ -1527,6 +1527,7 @@ static int git_default_core_config(const char *var, const char *value, void *cb) > > if (!strcmp(var, "core.hookspath")) { > if (current_config_scope() == CONFIG_SCOPE_LOCAL && > + (!value || (*value && strcmp(value, "/dev/null"))) && > git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0)) > die(_("active `core.hooksPath` found in the local " > "repository config:\n\t%s\nFor security " > diff --git a/t/t1350-config-hooks-path.sh b/t/t1350-config-hooks-path.sh > index f6dc83e2aab..1eae346a6e3 100755 > --- a/t/t1350-config-hooks-path.sh > +++ b/t/t1350-config-hooks-path.sh > @@ -41,4 +41,8 @@ test_expect_success 'git rev-parse --git-path hooks' ' > test .git/custom-hooks/abc = "$(cat actual)" > ' > > +test_expect_success 'core.hooksPath=/dev/null' ' > + git clone -c core.hooksPath=/dev/null . no-templates > +' > + > test_done > >> I have automation in place where I want my global Git Hooks to be >> ignored when cloning like this. The solution is to do this: >> >> GIT_CLONE_PROTECTION_ACTIVE=false git clone --config core.hooksPath=/dev/null https://github.com/bkuhlmann/infusible >> >> ...but is there a better, more secure, way to clone a repository while >> ignoring any global Git Hooks from firing without a lot of effort? > > That is certainly a good work-around for now. Thank you for the report! I > hope that we can address your use case in v2.45.2, hopefully soon. > > Thanks, > Johannes ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Git 2.45.1 - What is the right way to clone with global hooks disabled? 2024-05-16 12:13 ` Johannes Schindelin 2024-05-16 13:05 ` Brooke Kuhlmann @ 2024-05-16 14:56 ` Junio C Hamano 2024-05-17 13:08 ` Johannes Schindelin 1 sibling, 1 reply; 7+ messages in thread From: Junio C Hamano @ 2024-05-16 14:56 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Brooke Kuhlmann, git Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: > I plan on sending out a patch series later either today or tomorrow to > address a couple of regressions introduced by v2.45.1, and this patch > would address your specific scenario: > > -- snip -- > diff --git a/config.c b/config.c > index 85b37f2ee09..380f7777a6e 100644 > --- a/config.c > +++ b/config.c > @@ -1527,6 +1527,7 @@ static int git_default_core_config(const char *var, const char *value, void *cb) > > if (!strcmp(var, "core.hookspath")) { > if (current_config_scope() == CONFIG_SCOPE_LOCAL && > + (!value || (*value && strcmp(value, "/dev/null"))) && > git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0)) > die(_("active `core.hooksPath` found in the local " > "repository config:\n\t%s\nFor security " This does not make much sense to me. Why is /dev/null so special, compared to say /etc/passwd? I do think the defence-in-depth aspect of the other half of what went into 2.45.1 and friends, around the "hooks" theme has merit, i.e. "any activated hooks in the resulting $GIT_DIR/hooks/ directory that is different from what came from the templates directory is suspicious". It has a plausible attack scenario to realize such a suspicious configuration by using directory name munging and other tricks to confuse "git clone" into thinking what the repository sent as a part of its payload belongs to $GIT_DIR/. It did have fallout as the way "git lfs" mucked with user repository's metadata by abusing the overly wide trust the user gave to its smudge filter [*] crashed directly with the reasoning behind the "hooks must match template" protection, which is "Until the clone finishes and gives control back to the end user, external influence like hooks must not muck with the contents checked out without user's knowledge and consent before the user has a chance to inspect the resulting repository". And it is a reasonable expectation to have when cloning a repository that has not proven to be trustworthy. So instead of throwing the protection with bathwater, we should add a reasonable (i.e. easy to use for "git lfs" developers to follow) escape hatch that is a bit more nuanced than "rip out the whole protection" revert or "disable all of the GIT_CLONE_PROTECTION mechanisms" escape hatch 2.45.1 and friends had. But I cannot quite tell what the threat model this "core.hookspath" one is trying to protect against. If some attacker manages to muck with the configuration file, it is already game over, and they have better ways than pointing your hookspath to other places to take advantage of their ability to write to your configuration file to attack you. So, my recommendation for this one is to just rip the whole new logic added in 2.45.1 and friends out of the "core.hookspath" handling. [Footnote] * The user most likely consented only to allow the smudge filter to transform small token recorded in the object store into a large blob taken from elsewhere, which means it can read from the object store and write to the working tree, but the user may not necessarily agreed to give it full read/write/delete/create control over anything in $GIT_dir/ or in the configuration files. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Git 2.45.1 - What is the right way to clone with global hooks disabled? 2024-05-16 14:56 ` Junio C Hamano @ 2024-05-17 13:08 ` Johannes Schindelin 0 siblings, 0 replies; 7+ messages in thread From: Johannes Schindelin @ 2024-05-17 13:08 UTC (permalink / raw) To: Junio C Hamano; +Cc: Brooke Kuhlmann, git Hi Junio, On Thu, 16 May 2024, Junio C Hamano wrote: > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: > > > I plan on sending out a patch series later either today or tomorrow to > > address a couple of regressions introduced by v2.45.1, and this patch > > would address your specific scenario: > > > > -- snip -- > > diff --git a/config.c b/config.c > > index 85b37f2ee09..380f7777a6e 100644 > > --- a/config.c > > +++ b/config.c > > @@ -1527,6 +1527,7 @@ static int git_default_core_config(const char *var, const char *value, void *cb) > > > > if (!strcmp(var, "core.hookspath")) { > > if (current_config_scope() == CONFIG_SCOPE_LOCAL && > > + (!value || (*value && strcmp(value, "/dev/null"))) && > > git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0)) > > die(_("active `core.hooksPath` found in the local " > > "repository config:\n\t%s\nFor security " > > This does not make much sense to me. Why is /dev/null so special, > compared to say /etc/passwd? > > I do think the defence-in-depth aspect of the other half of what > went into 2.45.1 and friends, around the "hooks" theme has merit, > i.e. "any activated hooks in the resulting $GIT_DIR/hooks/ directory > that is different from what came from the templates directory is > suspicious". It has a plausible attack scenario to realize such a > suspicious configuration by using directory name munging and other > tricks to confuse "git clone" into thinking what the repository sent > as a part of its payload belongs to $GIT_DIR/. It did have fallout > as the way "git lfs" mucked with user repository's metadata by > abusing the overly wide trust the user gave to its smudge filter [*] > crashed directly with the reasoning behind the "hooks must match > template" protection, which is "Until the clone finishes and gives > control back to the end user, external influence like hooks must not > muck with the contents checked out without user's knowledge and > consent before the user has a chance to inspect the resulting > repository". And it is a reasonable expectation to have when > cloning a repository that has not proven to be trustworthy. So > instead of throwing the protection with bathwater, we should add a > reasonable (i.e. easy to use for "git lfs" developers to follow) > escape hatch that is a bit more nuanced than "rip out the whole > protection" revert or "disable all of the GIT_CLONE_PROTECTION > mechanisms" escape hatch 2.45.1 and friends had. > > But I cannot quite tell what the threat model this "core.hookspath" > one is trying to protect against. My thinking was this: if, for whatever reason, it is possible for a `git clone` to write to the Git directory during a clone (and I had those submodules and recursive clones in mind, in particular), then an attacker can not only manipulate Git into writing into the `hooks/` directory, but they can also reroute `core.hooksPath`. And if we ignore the latter, the former protections can be side-stepped rather easily. > If some attacker manages to muck with the configuration file, it is > already game over, and they have better ways than pointing your > hookspath to other places to take advantage of their ability to write to > your configuration file to attack you. Hmm. You have a good point there. The aforementioned `smudge` filter would be a prime target. > So, my recommendation for this one is to just rip the whole new > logic added in 2.45.1 and friends out of the "core.hookspath" > handling. I guess that's the easier path for now. We should seriously think about better ways to protect against config manipulations during clone operations, though. In particular with the current state of the submodule support code, recursive clones continue to seem like highly likely target for attackers. Ciao, Johannes > [Footnote] > > * The user most likely consented only to allow the smudge filter to > transform small token recorded in the object store into a large > blob taken from elsewhere, which means it can read from the > object store and write to the working tree, but the user may not > necessarily agreed to give it full read/write/delete/create > control over anything in $GIT_dir/ or in the configuration files. > ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-05-17 13:08 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-05-15 15:53 Git 2.45.1 - What is the right way to clone with global hooks disabled? Brooke Kuhlmann 2024-05-15 22:25 ` brian m. carlson 2024-05-16 14:59 ` Junio C Hamano 2024-05-16 12:13 ` Johannes Schindelin 2024-05-16 13:05 ` Brooke Kuhlmann 2024-05-16 14:56 ` Junio C Hamano 2024-05-17 13:08 ` Johannes Schindelin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).