{"thread":{"id":"65805","subject":"[RFC/PATCH] Suggestion: Safe Hook Verification for Unzipped/Local Repositories","startedAt":"2026-06-13T21:21:20Z","lastAt":"2026-06-13T21:53:41Z","messageCount":2,"participants":["Jamison Phillips","brian m. carlson"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"545470","messageId":"CA+pATbgyg3Wqg7NnScPx3hUmo8nG23EFx2QUXuVAd3nJ6Z_CPw@mail.gmail.com","threadId":"65805","inReplyTo":null,"subject":"[RFC/PATCH] Suggestion: Safe Hook Verification for Unzipped/Local Repositories","fromName":"Jamison Phillips","fromEmail":"jamisoncphillips@gmail.com","sentAt":"2026-06-13T21:20:43Z","receivedAt":"2026-06-13T21:21:20Z","isPatch":true,"body":"Hello Git Community,\n\nI would like to propose a defensive security enhancement regarding how\nGit handles hooks in repositories initialized outside of standard 'git\nclone' pathways (such as repositories downloaded and extracted via\nZIP/tarball archives).\n\n---\nTHE PROBLEM:\nWhen a user clones a repository, Git safely excludes the '.git/hooks'\ndirectory. However, if a developer downloads a project as a ZIP\narchive from an untrusted third party and extracts it, the archive can\ncontain a fully formed '.git/hooks' directory populated with\nmalicious, executable scripts.\n\nThe moment the developer runs a standard command like 'git checkout'\nor 'git status' inside this unzipped folder, the hooks execute\nimmediately without user consent or awareness. This is an active\nvector for supply-chain malware insertion on developer workstations.\n\n---\nPROPOSED FEATURE:\nI suggest implementing a \"Safe Hook Verification\" mechanism with the\nfollowing logic:\n\n1. First-Time Intercept: If Git detects executable scripts inside\n'.git/hooks' on a repository that does not have an explicit local\nclearance, it should halt execution and prompt the user: \"Warning:\nThis repository contains local hooks that have not been approved. Run\nthem? (y/N)\".\n\n2. Out-of-Directory Verification State: If the user approves ('y'),\nGit should log this approval by saving a unique cryptographic hash of\nthe approved hooks to a global state directory outside of the\nrepository's working tree (e.g., inside\n~/.config/git/approved_hooks/).\n\n3. Subsequent Runs: On future commands, Git will check the current\nhooks against the global hash map. If they match, they run silently.\nIf a hook file is modified or a new repository is unzipped, the prompt\nappears again.\n\n---\nIMPACT:\nThis would close a massive blind spot for developers interacting with\nshared zipped codebases, enforcing a model of explicit consent before\nthird-party code is executed locally by the VCS.\n\nI look forward to hearing your thoughts on the feasibility or\nalternative architectures for this defense-in-depth feature.\n\nRegards,\nJamison Phillips\n"},{"id":"545471","messageId":"ai3RXeTeTNmFfUuL@fruit.crustytoothpaste.net","threadId":"65805","inReplyTo":"CA+pATbgyg3Wqg7NnScPx3hUmo8nG23EFx2QUXuVAd3nJ6Z_CPw@mail.gmail.com","subject":"Re: [RFC/PATCH] Suggestion: Safe Hook Verification for Unzipped/Local Repositories","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2026-06-13T21:53:33Z","receivedAt":"2026-06-13T21:53:41Z","isPatch":true,"body":"On 2026-06-13 at 21:20:43, Jamison Phillips wrote:\n> Hello Git Community,\n\nHey,\n\n> THE PROBLEM:\n> When a user clones a repository, Git safely excludes the '.git/hooks'\n> directory. However, if a developer downloads a project as a ZIP\n> archive from an untrusted third party and extracts it, the archive can\n> contain a fully formed '.git/hooks' directory populated with\n> malicious, executable scripts.\n> \n> The moment the developer runs a standard command like 'git checkout'\n> or 'git status' inside this unzipped folder, the hooks execute\n> immediately without user consent or awareness. This is an active\n> vector for supply-chain malware insertion on developer workstations.\n\nGit's security model does not allow working with untrusted working\ntrees, period.  The only things we guarantee are safe to do with an\nuntrusted repository are clone and fetch from it.\n\nI'll also note that there are a variety of other methods that one can\nuse to execute arbitrary code with an untrusted working tree due to\nunsafe configuration options.  For example, one can set\n`filter.<driver>.clean` and `filter.<driver>.smudge` and execute\narbitrary code with a crafted repository.  This is why we don't let\npeople include config (or hooks) as part of the repository.\n\nMy concern is that we'd be misleading people that this was a safe way to\nwork by adopting your proposal when that is not true.  We would then be\ndeluged by a whole host of invalid security reports.\n\nWould you like to maybe share a little bit about why you (or others) are\ndistributing repositories as ZIP files instead of using the standard\nprotocol methods?  Perhaps we can offer some thoughtful comments about\nhow to achieve the intended goals with a better security posture.\n\n> PROPOSED FEATURE:\n> I suggest implementing a \"Safe Hook Verification\" mechanism with the\n> following logic:\n> \n> 1. First-Time Intercept: If Git detects executable scripts inside\n> '.git/hooks' on a repository that does not have an explicit local\n> clearance, it should halt execution and prompt the user: \"Warning:\n> This repository contains local hooks that have not been approved. Run\n> them? (y/N)\".\n\nHow would this work in a non-interactive situation?  If I install Git\nLFS, it installs hooks when its filter process is installed for the\nfirst time.  So if I then clone a repository using Git LFS in a CI job\nor a container build process, the hooks won't work and my repository may\nend up broken.\n\nNote that the Unix philosophy does not have tools prompt users by\ndefault.  If I say `rm -fr ~`, then my home directory gets blown away\nbecause that is what I asked for, even if that may have been improvident\nand imprudent; no prompt is expected.\n\n> 2. Out-of-Directory Verification State: If the user approves ('y'),\n> Git should log this approval by saving a unique cryptographic hash of\n> the approved hooks to a global state directory outside of the\n> repository's working tree (e.g., inside\n> ~/.config/git/approved_hooks/).\n\nThis is almost certainly going to grow indefinitely.  I've been copying\nmy entire home directory from machine to machine as I get a new one for\n19 years and I fully imagine that this would have grown quite a bit in\nthat time.\n\nAnother thing I think is worth noting is that just because I think a\nhook is safe in one context does not mean I think it's safe in another.\nA post-checkout hook that runs a particular command (say, `bin/setup`)\nfrom the repository might be safe on my dotfiles (which I exclusively\ncontrol and maintain), but an identical hook on a repository from Bob's\nMalware Emporium would probably not be a good idea.  Reusing safe code\nto do unsafe things has long been a favourite approach of attackers.\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"}]}