Assume a pure Git workflow without any forges such as GitHub. This means there is no protected branch settings for example.
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:
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.
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
to notice the action
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
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:
directly compare their content: git diff <sha1> <sha2>
compare their histories: git log --oneline --graph <sha1> <sha2>
or git log --oneline --graph --boundary <sha1>...<sha2>
do all sort of extra things ...
To understand the internals of Git, Chapter 10 of The Git Book is a very nice introduction.