TOFU: Do You Check?
Let’s say you’re on a fresh machine. Maybe you’ve just started a new job or you’ve wiped your machine. You’re about to push some code you’ve written and you get this:
$ git push The authenticity of host 'github.com (126.96.36.199)' can't be established. ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])?
What do you do next? You type
yes and hit enter. Like most of us do. How do you know you actually just pushed your code to
github.com? I’d wager the vast majority of people don’t verify the fingerprint. I don’t, but I’m going to start.
SSH operates on the principle of Trust On First Use. When you first connect to a server, you’re supposed to verify that the fingerprint matches what you expect. If it does, tuples of the host and its host keys are saved to
~/.ssh/known_hosts. If the fingerprint for some reason ever changes, OpenSSH will show you a big MITM warning and refuse to connect.
If you don’t verify the fingerprint, your SSH communications can be intercepted. When it comes to
git, this might enable an attacker to steal your code, although you would quickly notice something is amiss when your code doesn’t land on the remote and you get a warning later on when connecting to the real GitHub.
For server administration, verifying SSH fingerprints is critical. Although an attacker would not be able to act as a full man-in-the-middle and break into your server, they could present a shell that emulates the real server, perhaps tricking you into handing over a secret or password.
If you use SSH agent forwarding and your TOFU is tampered with, things become much more dangerous. The attacker gains the ability to impersonate you fully, enabling them to intercept and modify communications as a man-in-the-middle. They could modify or inject commands, or push to your git repository and loot CI secrets.
Do You Check?
You can find GitHub’s fingerprints here.
GitLab also has a nice documentation page.
Bitbucket’s are buried in a blog post.
Sourcehut’s are here, although they were not easily found via search engine.
It would really be nice if there were a standardised, well-known path for these.
I wonder if SSH should really be used at all for git. While TLS certificates are relatively short lived these days thanks to Let’s Encrypt, SSH host keys live a very long time. If GitHub’s SSH host keys were stolen, how long would an attacker get away with intercepting communications?