Git-hooks - Automatically check for secrets in your code

Posted in development on October 16, 2023 by Adrian Wyssmann ‐ 3 min read

Who did not once in his/her life commit secrets to the code and instantly regretted it? Well we can use git-hooks to avoid that.

What is it?

Based on Git-hooks - a practical example with tf docs I extended the git-hooks so it check for secrets and aborts the commit if secrets are found. All you neds it After that also install gitleaks, which is a SAST tool for

detecting and preventing hardcoded secrets like passwords, api keys, and tokens in git repos. Gitleaks is an easy-to-use, all-in-one solution for detecting secrets, past or present, in your code.

Configure pre-commit-hook

I create the following config, which also checks if gitleaks is actually installed, otherwise it skips the step

# @description: Check for secrets in current state and block commit, for secrets in commits only report them
function run_gitleaks() {
    ## skip setp if you add an empty file .skip_gitleaks
    if [[ -f "./.skip_gitleaks" ]]; then
        return
    fi
    if which gitleaks &>/dev/null ; then
        if [[ -z "$GITLEAKS_BASELINE" ]]; then
            GITLEAKS_BASELINE="./.gitleaks-report.json"
        fi
        if [[ -f "$GITLEAKS_BASELINE" ]]; then
            gitleaks detect $BASELINE --baseline-path "$GITLEAKS_BASELINE"
        else
            gitleaks detect -vls
        fi
    fi
}
run_gitleaks

I also added this part

## skip setp if you add an empty file .skip_gitleaks
if [[ -f "./.skip_gitleaks" ]]; then
    return
fi

This allows you do explicitly skip the gitleaks scan, for repositories you don’t want to be scanned - e.g. demo repositories or whatsoever.

Usage

You simply run a git commit or do a commit in your favorite editor. If secrets are detected you might see something like this


    │╲
    │ ○
    ○ ░
    ░    gitleaks


Finding:     "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef",
Secret:      cafebabe:deadbeef
RuleID:      sidekiq-secret
Entropy:     2.609850
File:        cmd/generate/config/rules/sidekiq.go
Line:        23
Commit:      cd5226711335c68be1e720b318b7bc3135a30eb2
Author:      John
Email:       [email protected]
Date:        2022-08-03T12:31:40Z
Fingerprint: cd5226711335c68be1e720b318b7bc3135a30eb2:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:23

Wo what do do if you find secrets?

Verify the secrets

Verify if this is a valid secret you can find details on how in the official docu. Based on the outcome you have the following options:

Remove the secrets

At first try to remove them or encrypt them if possible. If you have secrets in your history and you have admin permissions (or permissions to change main branch) you might also remove secrets from the history, following github - Remove sensitive files and their commits from Git history - Stack Overflow.

Baseline

When scanning large repositories or repositories with a long history, it can be convenient to use a baseline. When using a baseline, gitleaks will ignore any old findings that are present in the baseline. A baseline can be any gitleaks report. To create a gitleaks report, run gitleaks with the --report-path parameter.

gitleaks detect --report-path .gitleaks-report.json

The git-hooks checks for a file .gitleaks-report.json and will automatically use that as a baseline if exists. I believe for convenience you can commit this to your repo, so all developers use the same baseline.

gitleaks:allow

If you are knowingly committing a test secret that gitleaks will catch you can add a gitleaks:allow comment to that line which will instruct gitleaks to ignore that secret. Ex:

class CustomClass:
    discord_client_secret = '8dyfuiRyq=vVc3RRr_edRk-fK__JItpZ'  #gitleaks:allow