2

We started using git as VCS, with previously using SVN, and found out that in git you can easily distuingish the real person behind changes and commits. Now we are wondering why this design choice was made and if there is a thing we overlook.

Let's asume the following things:

  1. Everybody has registered an ssh key to gitlab
  2. Commits are not signed with gpg
  3. Everybody uses git bash using the registered ssh key

Now as we all know the author and committer is just meta-data for git and can easily be spoofed like this:

  1. git config --global --add user.email Incognito@fake.com
  2. git config --global --add user.name "Incognito User"
  3. git commit -m "You don't know who I really am" --author="Max Mustermann "
  4. git push

The metadata for the commit would then look something like this:

Author:     Max Mustermann <max.mustermann@company.com>
AuthorDate: Mon Jun 4 13:12:47 2018 +0200
Commit:     Incognito User <Incognito@fake.com>
CommitDate: Mon Jun 4 13:13:26 2018 +0200

Now I thought there has to be a way to find the used ssh key or real person for the commit, since the terminal and the system know the key and thus the real person behind the commit and push.

Question: Is there no way at all to find out the real person without using gpg signing?

PS: No, we don't distrust each other to exploit this, but we are rather curious and want to understand.

Nico
  • 1,727
  • 1
  • 24
  • 42
  • Pushes are not part of the history of either end, you're going to have to look at the logs of the remote you pushed to in order to see if it records something useful for verifying this. – Lasse V. Karlsen Jun 07 '18 at 14:55
  • Short answer is: No - Git is cryptographically secure, but it’s not foolproof. However, Git has a few ways to sign and verify work using GPG. – Yahya Jun 07 '18 at 14:57
  • 1
    Note: Aug. 2022, [GitHub does support SSH commit verification](https://stackoverflow.com/a/72852713/6309) – VonC Aug 23 '22 at 19:41

3 Answers3

2

Update - copying the information from torek's comment, because I believe this context is important enough that it should be available in the answer itself instead of just in the comments:


First, you need to separate git from gitlab. As far as git is concerned, ssh is just one of the possible protocols you might use to connect to your server. Your ssh key, or the validity thereof, doesn't matter to git; that's between you and your server as the server authenticates you so that it can decide if you're authorized to connect via ssh.

(The server might perform more granular authorization checks, especially for hosts like gitlab whose whole function is to integrate with git. Nonetheless, this is the host's business, not git's.)

Hosting services like gitlab may choose to log activity based on the ssh key, or they may not. Even if they do, that only tells you who pushed the commit into that server, which may not be the same as the author or the committer. For example:

Let's say Alice wrote the code; she's the author. She sent a copy of her work to Bob. Bob put the code into a local git repo. Bob is the committer. Bob created a bundle file and sent it to Cindy. Now Cindy loads Bob's commit containing Alice's code into her local repo, then pushes to gitlab using her ssh key. Now, git itself doesn't care about Cindy's role in this; she's not the author and she's not the committer. But if gitlab chooses to log activity based on ssh key, gitlab may log that Cindy introduced the commit to that server.

The method for creating verifiable commits in git is to use signatures[1]. So no, there is "no way at all to find out the real person without using [git's mechanism for recording the real person]".

Note that this arises from the distributed nature of Git. Without some sort of external constraint, it's impossible to say if Cindy is legitimately relaying Alice and Bob's work. With SVN, there's one clearly-distinguished central server / Source of Truth, and Alice must connect to that server to create a commit, after which Bob must connect to that server, and Cindy must connect to that server. Each individual connects individually to the server. Unlike SVN, Git does not assume this must always happen. If you want to enforce such a policy yourself, you can by having your server do it.

-torek


[1] And while I don't know if their views have changed, at least some of the git devs early on stated the belief that signing tags - not directly signing commits - is the right way to do it.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • 2
    Note that this arises from the distributed nature of Git. Without some sort of external constraint, it's impossible to say if Cindy is *legitimately* relaying Alice and Bob's work. With SVN, there's one clearly-distinguished central server / Source of Truth, and Alice must connect to that server to create a commit, after which Bob must connect to that server, and Cindy must connect to that server. Each individual connects individually to the server. Unlike SVN, Git does not *assume* this *must* always happen. If you want to enforce such a policy *yourself*, you can by having your server do it. – torek Jun 07 '18 at 15:07
1

I think a major difference between centralized and distributed comes from the fact that on centralized, you have to go through an authentication process in order to verify that "you are who you say you are" in order to be able to be trusted and then commit or do other stuff.

But on distributed everybody is the king/queen on their own kingdom. No need for me to authenticate against my own repo on my computer, right? And then remember that even though pushing is possible to do on distributed VCSs, it's actually designed for "pulling" so no one messes up with my repo. And who will I be pulling from? People that I trust, right? So there's still some trust involved, but it's on a different place and, ultimately, you are the owner of your own repo. No one can forcefeed you into accepting into your own repo a change you don't like. Linus' presentation on git for google from 2007 has all the basics explained. https://www.youtube.com/watch?v=4XpnKHJAok8

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • I just wanted to say even though I marked the other answer as solving, I still appreciate your input and your additional informations. – Nico Jun 08 '18 at 05:13
1

First: since Git 2.19 (Q3 2018), the new configuration variables gpg.format (can be set to "openpgp" or "x509"), and gpg.<format>.program (used to specify what program to use to deal with the format) means: you can use x.509 certs with CMS via "gpgsm" to be used instead of openpgp via "gnupg".

And gpgsm is a tool similar to gpg to provide digital encryption and signing services on X.509 certificates and the CMS protocol.
It is mainly used as a backend for S/MIME mail processing

(The Cryptographic Message Syntax (CMS) is the IETF's standard for cryptographically protected messages.
It can be used by cryptographic schemes and protocols to digitally sign, digest, authenticate or encrypt any form of digital data.)

So yes, there is a way (with Git) to find out the real person without using gpg signing.


Second, GitLab 12.8 (Feb. 2020) now supports "S/MIME Signature Verification of Commits"

Every commit in a Git repository has an author, but this is not verified by Git and means that it is easy to create commits that appear to be authored by someone else.
Commit signing allows you to prove that you are the author of the commit. This is important for sensitive projects and in some commercial environments.

In Git 2.19, OpenGPG signing and verification support was extended to include support for S/MIME using X.509 certificates, because managing these certificates is more friendly for large organizations.

GitLab now also supports S/MIME Signature Verification of commits, thanks to Roger Meier from Siemens! Further thanks go to Henning Schild, also from Siemens, for contributing this feature to Git in the first place!

CMS -- https://about.gitlab.com/images/12_8/x509-signing.png

See documentation, and issue 29782.

So yes, there is a way (now integrated with GitLab) to find out the real person without using gpg signing.


Since Aug. 2022, GitHub also supports SSH commit verification

SSH commit check


Since Dec. 2022, GitLab 15.7, commit signing with SSH is supported.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250