Securing Your GitHub Account
Tags: github, security
Published: 2020-03-11 18:38:51

Let's talk about some of the simple & practical steps you can take to improve your GitHub account security.

There's plenty of good reasons why you should try to keep any online account safe, but I feel that GitHub deserves special attention among developers. With automation through CI and CD taking center stage, it's not only important to you but also anybody who might rely on your code to ensure your GitHub account is secure.

# The Basics

Let's start with the basics, things that don't just apply to GitHub but to nearly any online service.

## Passwords

Let's face it, passwords freaking suck. We all know we're supposed to make them hard to guess and not to reuse them, but who has time to remember each and every password? Nobody, that's who.

But what if there was a solution where you could have unique passwords for each of your accounts, not have to remember them all, and have strong passwords that are difficult for both humans and computers alike to guess?

The solution is a Password Manager. A password manager is a bit of an abstract term that describes a way to record passwords for your accounts in a secure location. These managers can range from web-based services that tie in to your browser, or something as simple as a physical book you write in.

There are advantages and disadvantages to all of these options, but by properly using a manager you're protecting yourself from many common attack scenarios, the most common being password reuse.

If you're looking for a web-based solution, check out 1Password or LastPass. If you want something in-between consider KeepassX. If you want to kick it old school with a book, most office supply stores sell password books - but a good old fashioned phone book will work just as well.

## Two-Factor Authentication

Two-Factor authentication, sometimes called "Two-Step" or "Multi-Factor" (MFA), is a security measure provided by some websites to enhance your accounts security.

To understand why Two-Factor authentication works, you first need to understand what a "Factor" is.

### Authentication Factors

There are three common authentication factors: "What you know", "What you are", and "What you have".

Passwords and passphrases are things you know. Fingerprints and facial recognition are things your are. Lastly, your cell phone or a physical key are things you have.

One of the many problems with passwords is that while you may know them, other people can know them as well. To a website, it's very difficult to be sure who's who. With two-factor authentication, a website will require that you provide two forms of authentication. Most commonly this is your password, plus a one-time password generated by an app on your phone.

In the event somebody happens to have your password, with two-factor authentication they would also require your cell phone to get in to your account.

### Enable Two-Factor Authentication

1. Click on your Avatar in the top right and select "Settings"
2. Click on "Security" on the left hand side
3. Click on "Enable" under "Two-factor Authentication"
4. Click on "Set up using an app" ![Screenshot showing the setup page for configuring two factor authentication on github](https://dev-to-uploads.s3.amazonaws.com/i/wfvy5xmo6n4opnd2s5jh.PNG)
5. Save the recovery codes (Protip: If you're using a password manager, record the codes in the notes section for the websites entry)
6. Scan the QR code using authenticator app of your choosing
7. Enter the one-time password from your phone to finish setting up two-factor authentication

## Connected Apps

Like many online services, GitHub uses a technology known as OAuth to allow applications to interact with your GitHub account without requiring your username and password.

It's very important that you periodically review the applications you've authorized to use your GitHub account and remove any you no longer use.

1. Click on your Avatar in the top right and select "Settings"
2. Click on "Applications" on the left hand side
3. Click on the "Authorized OAuth Apps" tab
4. To revoke an app, tap on the "..." for the app and select "Revoke" ![Screenshot showing a list of authorized apps](https://dev-to-uploads.s3.amazonaws.com/i/rvepsqquou6btbs6e8j2.PNG)

## Active Sessions

GitHub lets you view active login sessions, and approximately where that computer or device is. It's always a good idea to periodically take a look at the list and ensure that only the devices you intend to use GitHub with are listed. If you see any login sessions from weird devices, or from the wrong country, it could be an indicator that your account is compromised.

To see your active sessions:

1. Click on your Avatar in the top right and select "Settings"
2. Click on "Security" on the left hand side
3. Scroll to the bottom of the page

Take the following example, where my current session is in Canada but a recent login occurred in Romania.

![Screenshot showing a three sessions with two in vancouver and one in romania](https://dev-to-uploads.s3.amazonaws.com/i/cm6klaak592htueb13ef.PNG)

If you see something out of the ordinary here, change your password immediately.

# GitHub as a Git Remote

Now that we've covered the basics, let's dive into the real reason why I'm writing this guide: GitHub is, obviously, a Git service.

## Avoid using SSH

GitHub, like nearly all Git services, lets you connect to it either one of two ways: using SSH or HTTPS.

From a cryptographic perspective, both of these provide strong encryption and protection against tampering, but there's a huge benefit to using HTTPS that SSH lacks: Public Key Infrastructure, or PKI. 

### Quick Primer: How PKI works for HTTPS

When you connected to dev.to to read this article your browser performed a TLS Handshake and trust verification with the web server hosting this site. Part of this process is the web server presenting its certificate to your browser. Your browser then looked at the parents of the servers certificate. If the browser trusts the root (or top-level) of the certificate chain, it can mathematically prove that the certificate was issued from a trusted authority, and after performing some additional tests, confirm that the web server is who they say they are.

![diagram of how PKI works](https://dev-to-uploads.s3.amazonaws.com/i/ro6yi9rhg3m8jtugqvvg.png)

### Why SSH is the wrong choice for Git

SSH lacks nearly all of this, especially all of those additional checks that are done.

When you connect to a host using SSH your computer only has the servers public key to go on to determine trust. If you've never connected to server before, it will prompt you if you want to trust their public key. The next time, if the public key matches it will connect without asking you, but if the public key changes it will show this scary warning at you.

![screenshot of SSH host key verification error](https://dev-to-uploads.s3.amazonaws.com/i/3fp4f1b5129u7niec3va.png)

The fatal flaw with SSH's trust mechanism is placing ultimate and permanent trust in the hosts key. Once you've trusted a key, that key can never change without causing errors as seen above. In GitHub's case changing their key would cause huge confusion among its users.

Whereas with HTTPS, GitHub's certificates are [rotated regularly without you even realizing it](https://crt.sh/?q=*.github.com).

SSH also lacks a large amount of other security enhancements that HTTPS has, such as: certificate lifespans, revocation and automatic status checks, transparency, and key usage restrictions.

Now that I've lectured you enough on why SSH is not the right choice, let's look at how we can go about using HTTPS.

## Using Access Tokens

Git over HTTPS works just like Git over SSH, you just have to sign in to GitHub with your username and password instead of adding your SSH key to your account.

However, if you're using Two-Factor authentication (You are, right? See the section above). You won't be able to use Git over HTTPS since there's no way to prompt for your one-time password.

Not to worry though, GitHub has you covered with so-called "Access Tokens". These are sometimes called "Application Passwords" on other services and let you sign in on applications that don't support multi-factor authentication. The idea is that you sign in and generate these passwords but only use them for a specific application.

Here's how you generate an access token:

1. Click on your Avatar in the top right and select "Settings"
2. Click on "Developer Settings" on the left hand side
3. Click on "Personal Access Tokens" on the left hand side
4. Click on "Generate New Token"
5. Give the token a name and select only the required permissions for the token

![screenshot showing the setup page for a github access token](https://dev-to-uploads.s3.amazonaws.com/i/sfpz5hb9xzxtszi8ug2c.png)

Then, when you configure your git remote to use HTTPS you'll be asked to provide your username and password. Use the access token as your password and you've authenticated.

```
$ git fetch
Username for 'https://github.com': ecnepsnai
Password for 'https://ecnepsnai@github.com': <my access token>
```

## Storing Access Tokens

There are 4 options to store your credentials if you don't want to type your access token every time (Who would?)

**Option 1: Don't store them**

Didn't I just ask who wants to type their access token out each time? With this, git doesn't remember your credentials. Each time you access the remote, you have to type in your credentials.

**Option 2: Cache them for a limited time**

This method is marginally better than option 1. Git will remember your username and access token for a limited period of time before requiring you to enter them again. This is similar to how `sudo` works if you've used that before.

You can enable this method using:

```
$ git config --global credential.helper 'cache --timeout=3600'
```

Where `3600` is the number of seconds to cache the credentials.

**Option 3: Store them in a plain-text file**

This method is the easiest to set up, but not the most secure. With this, git will store your username and access token in a plain-text file in your home directory. It won't prompt you for your username or access token once saved.

You can enable this method using:

```
$ git config --global credential.helper store
```

**Option 4: Store them using a credential helper**

This method can be tricky to set up but provides the best balance of convenience and security. A credential helper is an application that stores keys in a secure location that git can use.

On macOS you can use the systems Keychain, which is encrypted with your users password. See [GitHub's documentation](https://help.github.com/en/github/using-git/caching-your-github-password-in-git) on how to setup and configure the credential helper.

On Linux you can use the `gnome-keyring` package, which is very similar to the Keychain from macOS. Setup varies depending on your distribution and isn't covered in this document.

# Anything Else?

That's all for the tips I have in this guide. Do you have any other ideas on ways to protect your account? Let me know in the comments!