Improving Git protocol security on GitHub

Image of Matt Cooper
   
Image of brian carlson

Hello from Git Systems, the team at GitHub that makes sure your source code is available and secure. We’re making some changes to improve protocol security when you push or pull Git data. We expect very few people will notice these changes since we’re making them as seamless as possible, but still wanted to give plenty of notice.

What’s changing?

We’re changing which keys are supported in SSH and removing unencrypted Git protocol. Specifically we are:

  • Removing support for all DSA keys
  • Adding requirements for newly added RSA keys
  • Removing some legacy SSH algorithms (HMAC-SHA-1 and CBC ciphers)
  • Adding ECDSA and Ed25519 host keys for SSH
  • Turning off the unencrypted Git protocol

Only users connecting via SSH or git:// are affected. If your Git remotes start with https://, nothing in this post will affect you. If you’re an SSH user, read on for the details and timeline.

We recently removed support for passwords over HTTPS. These SSH changes, while unrelated on a technical level, are part of the same drive to keep GitHub’s customer data as secure as possible.

Why are we making these changes?

Public key cryptography depends on secure algorithms and sufficiently strong keys to remain secure. “Fewer bits” generally means “easier to brute force,” and older algorithms have known attacks. What was considered secure in, say 2001, might no longer be acceptable today given changes in computing power, new attacks, and so on.

Dropping old key types

DSA keys offer only an 80-bit security level. This is low (128-bit is fairly standard), and fewer than 0.3% of GitHub requests are still using DSA. We feel confident that rejecting these keys altogether will increase security with little or no user friction. We’re also planning to remove support for our DSA host key.

Pie chart showing requests by signature type: ssh-rsa 45%, ssh-ed25519 7.3%, ssh-dss 0.3%, rsa-sha2 47%, ecdsa-sha2 0.4%

Dropping insecure signature algorithms

RSA keys (you’ll see ssh-rsa in the public key) are stronger than DSA keys, but older Git clients may use them in combination with a dated signature algorithm that uses SHA-1. Many SSH clients, including OpenSSH 7.2 and newer, support RSA with SHA-2 signatures (signature types rsa-sha2-256 and rsa-sha2-512), which are secure. However, other clients only support the older SHA-1 signatures. SHA-1 is weak, so we’ll stop allowing new RSA client keys to use SHA-1 signatures and require them to use SHA-2 signatures instead. Keys with a valid_after date before the deadline (November 2, 2021) may continue to use SHA-1 signatures for the time being.

Dropping insecure algorithms

There are additional algorithms we’ll be removing for our SSH service. The hmac-sha1 message authentication code will be removed, as will all CBC ciphers (aes256-cbc, aes192-cbc, and aes128-cbc). The CBC ciphers in particular are known to be relatively practical to attack, and our data shows that almost all clients offer better encryption and MAC algorithms.
Pie chart showing requests by cipher type: chacha20 50%, *-gcm 18.1%, *-ctr 31.9%, *-cbc 0.1%

Pie chart showing requests by HMAC + best MAC

New host keys

ECDSA and Ed25519 are newer standards based on elliptic curve cryptography. They offer good security characteristics for modest size and computation increases. GitHub hasn’t traditionally offered these as host keys (server keys), but we’ll be offering them as options in the future. We’ll be shipping them in advance using OpenSSH’s UpdateHostKeys extension, which uses a secure technique to prove that GitHub owns the new keys it’s proposing. The new host key fingerprints for these keys are as follows:

  • ECDSA: SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM
  • Ed25519: SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU

The actual host keys are these: ecdsa-sha2-nistp256 AAAAE2VjZHNhL

  • ECDSA:
    ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
  • Ed25519:
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl

No more unauthenticated Git

On the Git protocol side, unencrypted git:// offers no integrity or authentication, making it subject to tampering. We expect very few people are still using this protocol, especially given that you can’t push (it’s read-only on GitHub). We’ll be disabling support for this protocol.

When are these changes effective?

Date What happens
September 14, 2021 New host keys offered via UpdateHostKeys.

We’ll start offering ECDSA and Ed25519 host keys through the UpdateHostKeys extension.

November 2, 2021 First brownout; RSA with SHA-1 cutoff.

All user RSA keys with valid_after dates after this point will need to use SHA-2 signatures during the brownout periods and after the change becomes permanent. We’ll also run several short brownouts on this date. During a brownout, the MACs, ciphers, and protocol we’re removing will be temporarily disabled.

November 16, 2021 The ECDSA and Ed25519 host keys will start to be fully usable. GitHub’s DSA host key will no longer be supported.
January 11, 2022 Final brownout.

This is the full brownout period where we’ll temporarily stop accepting the deprecated key and signature types, ciphers, and MACs, and the unencrypted Git protocol. This will help clients discover any lingering use of older keys or old URLs.

March 15, 2022 Changes made permanent.

We’ll permanently stop accepting DSA keys. RSA keys uploaded after the cut-off point above will work only with SHA-2 signatures (but again, RSA keys uploaded before this date will continue to work with SHA-1). The deprecated MACs, ciphers, and unencrypted Git protocol will be permanently disabled.

How do I prepare?

Again, only users connecting via SSH or git:// are affected. If your Git remotes start with https://, nothing here will affect you.

Standard Git client

If you’re running Git from the command line and using OpenSSH, make sure that you’re using OpenSSH 7.2 or newer, which you can verify with ssh -V. You can also use OpenSSH versions as old as 6.5 with Ed25519 keys or 5.7 with ECDSA keys. We’ve also provided a helpful script in this repository, which you can run to verify that your keys are properly configured. Also, we recommend adding the following configuration stanza to your ~/.ssh/config:

Host github.com
    UpdateHostKeys yes

If you’re using PuTTY with Git, make sure you’ve upgraded to 0.75 or newer, which you can check with putty --version.

libgit2 and other Git clients

If you’re using libgit2 or another piece of code using libssh2, we recommend you use libssh2 1.9.0 or newer and an ECDSA key, since it does not yet support RSA with SHA-2. Similarly, the Go SSH client also doesn’t yet support RSA with SHA-2, so we recommend using an Ed25519 key there.

Check your keys

Make sure that you’re ready to accept our new host keys. You can check the fingerprints above and save the keys in a place suitable for your SSH client.

If you’re using a DSA (ssh-dss) public key, regenerate and upload a new SSH key, such as an Ed25519 key.

What should I do if things are broken after this change?

SSH troubleshooting

If SSH was working before the change and fails afterward, you may be using an older operating system or have older SSH libraries. You can get detailed information about GitHub’s supported SSH algorithms and what your client presents by running ssh -vvv git@github.com. If your client is trying to negotiate one of the deprecated key types or fingerprint types, you may need to create a new SSH key and upload it to GitHub.

Clients relying on older SSH implementations will need to be updated. (The standard Git client uses your operating system’s SSH implementation on Linux and macOS.) Common examples include:

  • OpenSSH before version 7.2
  • PuTTY before 0.75

GitHub has worked with these vendors to make new versions of their packages available.

CentOS 6 and Ubuntu 14.* ship with old versions of OpenSSH. While you may be able to upgrade them to a newer OpenSSH version, note that these operating systems are end-of-life and thus unsupported by GitHub.

Git protocol troubleshooting

If you’re having trouble cloning a repository, make sure the URL starts with ssh://, https://, or git@github.com.

For existing repositories, if you’re having trouble fetching, check that the remote you are fetching from is an ssh:// or https:// URL, or an SSH pseudo-URL starting with git@github.com. You can run git remote -v in the repository to see the URLs for all remotes. If any of them start with git://, you should change the URL to a supported format.

What’s next?

We’re always keeping an eye on the latest developments in security, attacks in the wild, and use of features in order to keep the GitHub community secure. We’ll continue to watch RSA with SHA-1 usage. Once it declines naturally, we’ll update the community on plans to deprecate it.