Git security best practices

Paul-Emmanuel Raoul (Software Engineer and Researcher)

git security best practices

In this article, we will discuss different methods to avoid some common pitfalls when it comes to Git security.

We live in a world where it is hard not to know about Git, the most popular Distributed Version Control System (DVCS). Free and open-source, it has been initially created by Linus Torvalds for the development of the Linux Kernel. These days, Git is completely omnipresent in the IT industry. It is the key element of platforms such as GitHub or GitLab and used as a package management system by the Go language.

    Common Git security issues and how to avoid them

    1. Do not commit sensitive information

    Committing sensitive information can lead to critical situations and happens more often than you might think. In particular, with the emergence of cloud providers, continuous integration of online services and the Infrastructure as Code (IaC) paradigm, our source codes now contain access tokens, IP addresses, etc. Even a .DS_Store (a hidden file present in every folder on an OS X system) can leak the name of the files and folders present on a web server and a quick search on GitHub returns more than 800 000 results (see “Scanning the Alexa Top 1M for .DS_Store files” for further information).

    The first thing to do to avoid such situations is to add a .gitignore file into your code repository which contains the files that Git should intentionally ignore and thus keep untracked. Private keys are an obvious example of what should be ignored by Git (*.pem, *.key,) but other sensitive files are harder to anticipate. Text editors such as vim or gedit create backup files (respectively .<filename>.swp and .<filename>~) of your work and can be committed by accident. If the content of a Git repository containing a PHP web application is pushed into production, a db.php file with the database credentials would be probably accessible via its backup file through the web server without triggering any error.

    Even if we suppose that your .gitignore contains all the potential sensitive files of your project, it won’t stop inadvertency commiting of an access token in a file legitimately tracked by Git. Solutions like git-seekret can be used to address this issue. This tool leverages Git hooks to inspect the content of your staged files or commits and checks whether sensitive information has been added based on customized rules.

    If, despite these preventive measures, sensitive information can be found in your Git repository history, git-filter-branch is here to help you fix it. This Git feature allows you to rewrite the Git revision history of your project using filters. Other third-party solutions also exist such as BFG Repo-Cleaner and are quite easy to use:

    bfg --delete-files id_{dsa,rsa} my-repo.git

    The above line (taken from the BFG documentation) deletes all files named id_rsa or id_dsa from the Git history of my-repo.git.

    2. Guard the access to your Git repositories

    Another critical Git security issue you should guard against is unauthorized access to your Git repositories. Git by itself only takes care of keeping track of the changes occurring inside a repository. When you want to share your work, you need to expose this repository, and you should do it in a secure manner, otherwise, you can get into trouble.

    Git stores internal files inside a hidden .git folder which is itself contained inside your Git repository. These internal files contain the whole history of your committed changes. In other words, the .git folder is your Git repository and consequently should never be exposed to people not authorized to clone it. Using Git to version websites is a common practice and restricting access to the .git folder from the production servers is not always done correctly.

    From a network perspective, your best choice is to rely on HTTPS or SSH to encrypt your traffic and authenticate the remote server. When using SSH (recommended), your private key should be protected by a passphrase and never leave your computer. If you have several development workstations, create one pair of SSH keys for each of them. This way, it would be easy to revoke access to your Git repositories for a specific device that you believe may have been compromised. The same is true when you give third-party applications access to your Git repositories. Use access tokens that can be easily revokable instead of your account credentials and make sure to keep them secret. The Homebrew project recently disclosed a Git security incident where a GitHub personal access token has leaked through their Jenkins instance’s logs.

    When using development platforms like GitHub or GitLab, the Two-Factor Authentication (2FA) logging method should be enabled for your account. It means that each time you want to connect to your online account, you will be prompted to enter a One Time Password (OTP) which constantly changes after a short period of time. Instead of text messages, opt for the use of a mobile application to generate the OTP. For the security of your data, you may consider it worthwhile to invest in this additional security, in which case a hardware token is the best option (for example, a YubiKey).

    3. Sign your work

    Git enables you to cryptographically sign your work using GPG keys. Signing your work is important because anyone can choose the name and the email address of the author displayed in the Git commits. Both Git commits, tags, and even push requests, can be signed since version 2.2.0. However, in practice, it is pointless to sign each commit since many operations would invalidate those signatures (see Linus Torvalds’ arguments on this point). Only Git tags need to be signed.

    As with any asymmetric cryptosystem, security measures should be taken:

    • Don’t use short-length keys. Today, 4096-bit keys are recommended.
    • When creating a new key pair, don’t forget to generate a revocation key and store it in a safe place.
    • Protect your private key with a passphrase.
    • Avoid using an infinite validity period for your keys. If you ever lose a key and can’t revoke it for some reason, it becomes a ticking time bomb.

    Even if signing your work is an excellent way to add an extra layer of trust, the ultimate proof of trust is still to review the source code instead of blindly accept any contribution.

    As is true of software in general, Git is not perfect and can be impacted by vulnerabilities. The recent CVE-2018-11235 is a good example of this, allowing an attacker to craft a malicious Git repository leading to remote code execution when cloned by someone. Any Git-related tool can be impacted by similar issues and they all need to be kept up to date. We recommend that you subscribe to security advisory feeds and read them carefully. Here is an example of such a security bulletin made by GitLab.

    Share this post on social media!

    More Articles

    Deserialization vulnerabilities in Java

    Deserialization vulnerabilities in Java

    Understanding serialization and deserialization vulnerabilities is the first step toward building secure applications. For most developers, it’s a challenge to find the right balance between coding securely and meeting other objectives like tight deadlines. This often results in products that are vulnerable to deserialization attacks which would be otherwise difficult to stage.

    JWT handling best practices

    JWT handling best practices

    The purpose of this post is to present one of the most popular authorization manager open standards JWT. It goes into depth about what JWT is, how it works, why it is secure, and what the most common security pitfalls are.

    Ruby needs security

    Ruby needs security

    Every year, Ruby is becoming more and more popular thanks to its elegance, simplicity, and readability. Security, however, is an issue we can’t afford to neglect.