Skip to main content

% 16k.es

I Leaked My Secrets to Github

Sunday evening. I was writing stupid code in a cold, rainy day.

After a long day of coding, things were finally working. I was using a cloud service for… whatever. I was tired, and I wanted to push my code to github.

As usual, I created a copy of the configuration file and redacted it to remove the secrets (the precious API_KEY).

trufflehog can save your day

With this done, I opened .gitignore to add the configuration file. The usual drill.

Then I heard my name. My wife complaining, it was time for dinner so I prepared something quick and went back to the keyboard.

I took a last look at the .gitignore file I was editing. Distracted, I closed it, and then I ran git add .

And git commit -m "whatever".

And git push origin main.

I leaned back in my chair and, suddenly, I got a shiver.

Did I add save .gitignore with configuration file?

I didn’t even have to check, I knew the answer. At that moment I was not sure if it is really possible to completely wipe a secret from git (and I’m still not 100% sure) so I just rushed to remove the repository before someone could find it.

things that can ruin your life

Iy was fast but, how long does it take for a leaked secret to be found? Minutes? Seconds?

Of course I had to invalidate the key just in case.

## How to prevent this?

This should not happen again. But shit happens!

There are tools that can scan your code for secrets; but relying on a manual scan may not be a good idea. It’s like eerrr.. relying on me editing .gitignore correctly or moving the secrets out of the workspace while writing stupid code.

This should be done automatically.

One of these tools os truflehog.

Trufflehog is able to scan different targets (a git remote repository, a filesystem, syslog, travis, jenkins…) It comes in several flavors but it has a free/open source version, so I can check it out.

I do not for sure but it seems to be a combination of regex and entropy calculation. This approach may lead to false positives, so you have to be careful. Needless to say false negatives as possible as well!

In any case, I checked my repository:

$ trufflehog filesystem --config=generic.yml --no-update -x exclusions.txt Projects/ai-commit/
🐷🔑🐷  TruffleHog. Unearth your secrets. 🐷🔑🐷

2024-10-21T22:33:12+02:00	info-0	trufflehog	running source	{"source_manager_worker_id": "8C7xP", "with_units": true}
Found unverified result 🐷🔑❓
Detector Type: CustomRegex
Decoder Type: PLAIN
Raw result: api_key = *****************
Name: generic-api-key
File: Projects/ai-commit/config.ini
Line: 2

[...] trufflehog	finished scanning	{"chunks": 4, "bytes": 2005, "verified_secrets": 0, "unverified_secrets": 1, "scan_duration": "16.016782ms", "trufflehog_version": "3.82.11"}

Voilà, here you have the (potentially) leaked key. Kudos to trufflehog!

## automating the check

We’ve seen how to run truffeohog manually, but we can also automate the check. For example, we can add a github hook script that runs trufflehog before we commit: a pre-commit script.

Setting up the pre-commit script is easy: just write the .git/hooks/pre-commit script and make it executable.

#!/bin/bash

[...]

# avoid commiting secrets!
p_dir=~/Projects/ai-commit
/usr/local/bin/trufflehog filesystem --config=generic.yml --no-update -x ${p_dir}/exclude.txt --json --fail ${p_dir} >/dev/null 2>&1

if [ $? -ne 0 ]; then
    echo 
    echo "=================================="
    echo "          WARNING!!!              "
    echo "Check your code for leaked secrets"
    echo "=================================="
    echo 
    exit 1
fi

Caveats:

  • the script must be named pre-commit and must be executable
  • the script must exit with a non-zero status if it fails (in this case, if it finds a secret)
  • make sure that config.hooksPath exists:
git config --local core.hooksPath .git/hooks

Example:

$ git add .
$ git commit -m "i should not push this..."

==================================
          WARNING!!!              
Check your code for leaked secrets
==================================

and the commit is aborted.

I’m running to deploy it in all my applications before it’s too late.