Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Comments on Is `git pull` dangerous?

Parent

Is `git pull` dangerous?

+4
−2

I heard git pull is dangerous.

  • Is it really dangerous?

  • If so, why or how is it dangerous?

  • Are there any flags that mitigate or remove the danger?

  • What are the alternatives if it is dangerous?

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

1 comment thread

Unclear (3 comments)
Post
+10
−0

While any piece of software receiving input from an untrusted source is additional attack surface, generally speaking git pull is not a security threat.

Three things happen when you git pull: a git fetch, a git merge or git rebase (depending on config), and any hooks you've defined may fire.

Starting with the last, the hooks are arbitrary scripts that can do anything before/during/after a pull. As such, hooks very much could harbor a security vulnerability, but you have to decide to add such hooks. A git pull can't add hooks itself.

git fetch is the step that actually retrieves data from the remote source. It basically just downloads it. There's a potential for a denial of service attack via resource exhaustion, e.g. using a lot of disk space or bandwidth, but that's about it.

While git will verify TLS certificates and such, it doesn't really "authenticate" the repository. Given the distributed model, this doesn't really make much sense. There are three scenarios for malicious input here: 1) extra "detached" commits, 2) changing history, 3) commits to a branch (including the main branch). The first doesn't really accomplish anything, such commits won't even be attempted to be merged in. The second is cryptographically hard to do. The attacker could make a different history, but that would not be silently merged at all. The last is a real problem but comes down to whether you trust the person who wrote the commit and this is addressed by commit signing.

git merge/git rebase is an entirely local operation but, of course, it's working on data gathered from a potentially untrusted source. The actual merge or rebase is just editing the source files and metadata. Besides any hooks, no "user code" is being executed. The main risk is that commits themselves introduce malicious code into the codebase. Commit signing can mitigate this, but, ultimately, the only way to be "sure" is to audit the changes yourself.

All told, the risk of a git pull itself pwning your machine is low.


The self-answer seems to define "dangerous" as "causes you an inconvenience". While I endorse restricting to only fast-forward pulls, the first issue in that answer is really with automatic conflict resolution. --ff-only alerts you to this consideration, but you still have to review the changes. Or, you know, don't, because the automatic merging logic is usually fine, and when it's not it is highly likely to break the build and/or tests.

The second issue that self-answer puts forward is purely an inconvenience, and the solution is not painstakingly verify all commits you're about to merge, but knowing how to back out of the problem if it happens. Specifically, the problem is that you may want to "undo" even a fast-forward merge. Of course, you have all history so this is certainly possible, but you need to know the hashes. The solution, git log -g or git reflog. These list the reflog which is a record of the commands that changed a reference (such as HEAD). So if you git pull --ff-only and decide you want to change your mind, you can simply run git log -g or git reflog and get the commit hash immediately preceding the pull which will be plainly recorded.

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

1 comment thread

git-reflog(1) is inconvenient (6 comments)
git-reflog(1) is inconvenient
alx‭ wrote 3 months ago

Hmm, I agree. Dangerous was too strong of a word; I've lessened that to clarify that it's not a security concern, but just an inconvenience.

However, I don't agree that git-reflog(1) solves the inconvenience. It is part of the inconvenience. It just makes it not a total disaster. But a git-log(1) before merging is (IMHO) better than a reflog afterwards.

Derek Elkins‭ wrote 3 months ago

Sure. If you have some reason to think the next merge/rebase may cause issues, getting the hash ahead of time may be a bit more convenient. That said, a git fetch won't change the git log output, so you could just as well git log before the git pull. If you meant to actually look at the log of commits for the fetched changes, then, sure, that's what git fetch is for.

That said, in my experience a git pull is almost always to sync some branch to its latest state. The actual merge that might be problematic is when I want to merge changes into my branch which wouldn't be a pull anyway. Generally, the only time a git pull has been "risky" for me is in the rare cases when I was working independently to someone else on the same branch.

alx‭ wrote 3 months ago · edited 3 months ago

Most of the time it doesn't, but when it does it's already late. :)

And yes a git-log(1) before the pull/fetch should be enough for being able to revert, but then it's harder to see the diff, that is, see what's only on the remote.

Even if you trust the author of the remote, you may not trust the remote (it might be hacked). To be cautious, I'd at list like to see at first glance a one-liner list of changes that I'm pulling, so I can see if those are properly signed. My full list of git aliases is:

[alias]
	lgo = log --graph --oneline --abbrev=12
	lago = lgo --all
	lg = log --graph --abbrev=12 --decorate \
		--format=format:'%C(bold blue)%h%C(reset) %C(magenta)%G?%C(reset) - %C(bold cyan)%ai%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n''  %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
	tree = lg --all
	ff = merge --ff-only

With git tree, which is what I use after a fetch, I print with %G? a small status of the signature of each commit. ...

alx‭ wrote 3 months ago

git-log(1):

             %G?
                 show "G" for a good (valid) signature, "B" for a bad
                 signature, "U" for a good signature with unknown validity, "X"
                 for a good signature that has expired, "Y" for a good
                 signature made by an expired key, "R" for a good signature
                 made by a revoked key, "E" if the signature cannot be checked
                 (e.g. missing key) and "N" for no signature

So I can see there are 10 new commits in the remote, and that they are signed. Even for my own server, that makes me confident that I'm pulling my own commits, and not some malicious changes.

Derek Elkins‭ wrote 3 months ago

This is more compelling, but it is also what git merge/pull --verify-signatures is for. If you expect all commits to be signed you can set the config merge.verifySignatures to true to have this happen automatically. In the case where you expect a mix of signed and unsigned commits, then you can run git pull --verify-signatures. If succeeds, it will proceed with the merge without you needing to painstaking check for a bunch of "G"s. If it fails, then it will tell you which commits failed and you can check those specifically and then git merge without --verify-signatures once you've checked them all (assuming they look good). This lessens the chance that you simply fail to notice an unverified commit, or you don't check because you're in a hurry. Even better if you set merge.verifySignatures and only disable it via --no-verify-signatures when you need to.

And it's only "too late" to check after merge in the sense that it's inconvenient, though it is better to check before.

alx‭ wrote 3 months ago

I wish I could do that, but I have to work with other authors who don't sign their commits. :|

But yeah, that's something quite useful for my own projects. Thanks!