gitsecurity

`git push --force` to send malicious codes to other developer's local env without notice?


Assume a pure Git workflow without any forges such as GitHub. This means there is no protected branch settings for example.

Safe Workflow

When a malicious member executes git push (without --force) to push a malicious code and then another member executes git pull, he can notice he has downloaded (or pulled) something new:

enter image description here

If he is conservative enough, he can check the actual diff by using the command below:

$ git diff 71bbeab..984e12a

After that, if he is suspicious about the diff, he can opt not to blindly type make, which may execute the malicious code.

Unsafe? Workflow

Assume a situation which is the same as the one above except that the malicious member executes git push --force and may additionally execute some hacking tricks which I don't know.

In that case, is it still always possible for other members

  1. to notice the action

  2. and to check the actual diff?

As for the first point, as far as I tested, it seems they can notice the action because git pull shows forced update when pulling a change created via git push --force:

 + 31674dc...71bbeab master     -> origin/master  (forced update)

As for the second point, again as far as I tested, it seems they can also check the diff because git pull either fails due to merge conflicts or succeeds but shows the diff as shown in the Safe Workflow above, though I don't know there is any attacker-controllable way to make git show a fake diff.


Edit: As discussed in the comments, this question is about security considerations, so "as far as I tested" is not enough; we know that security questions must be answered theoretically and not empirically or experimentally. This is why I also explicitly wrote

and may additionally execute some hacking tricks which I don't know

though I don't know there is any attacker-controllable way to make git show a fake diff


Solution

  • Commits are uniquely identified by a hash which validates their content and their parents. So any push action (so called "malicious" or not) can always be detected: the hash at the tip of the branch you fetch will change. There is no circumventing that.

    In the output you pasted in your question: you can see the two sha in 71bbeab..984e12a.

    To inspect after the facts (say you closed your first terminal, or ran git pull --quiet) the changes on a remote branch (say: origin/master), you can run: git reflog origin/master to view the various updates you saw -- e.g: the history of how origin/master was updated each time you ran a git fetch or git pull (warning: this is not a long term history, git reflog entries may expire after 90 days by default, see git help reflog).

    Once you have these two commit identifiers, you can:


    To understand the internals of Git, Chapter 10 of The Git Book is a very nice introduction.