Prevent Committing Secrets!
photo credit: DALL-e

Prevent Committing Secrets!


In the fast-paced world of software development, security mistakes often happen—not always because developers don’t know better, but because of deadlines, pressure, or a lack of process. One of the most common and dangerous mistakes? Accidentally committing API keys, passwords, or database credentials to version control.

Once a secret is pushed to a repository, it’s at risk—whether it’s a public or private repo. Attackers can scrape repositories, expose sensitive data, and even gain unauthorized access to critical systems. Unfortunately, many startups and teams without experienced developers or strong code review processes fall into this trap, especially under pressure to "just get it working."

I would like to share here some practical ways for developers/leads to prevent secrets from ever being committed to Git repositories.


Why Committing Secrets is a Problem

  • Public Secrets in Public Repositories: Attackers constantly scan repositories for exposed keys. Also we know about available API KEYS with GenAI.
  • History is Forever: Even if you delete a secret, it remains in Git history unless properly removed.
  • Revoking Leaked Secrets is a Pain → You need to rotate keys and update configurations everywhere.
  • A well known short horror story: Someone pushed the AWS S3 secret in the config file mistakenly and requested a friend to review the code. After noticing the mistake he removed and cleaned the repo within 10 minutes only. But the secret was leaked already and after a month he got a bill of 14+ thousand dollars!!
  • Automated Scanning – Attackers use bots that constantly scan GitHub, GitLab, and Bitbucket for leaked credentials. These bots act within seconds to minutes of a leak.
  • Unauthorized Usage – Once attackers get AWS credentials, they usually:

Deploy crypto-mining (which consume expensive EC2 instances and GPU power).

Set up proxy services for illegal activities.

Store large amounts of pirated content on S3.


Solution? Proactive Prevention!

Step 1: Use .gitignore to Prevent Accidental Commits

First, make sure that sensitive files are ignored by Git. Add the following to your .gitignore file:

# Ignore environment files
.env
*.pem
*.pfx
*.key
*.crt
*.enc
config/*.json
secrets.yml        

? This ensures that Git does not track these files.


Step 2: Use Environment Variables Instead of Hardcoded Secrets

Instead of storing credentials in code, use environment variables and key vault/manager.

Linux & Mac:

echo "export API_KEY='your_api_key'" >> ~/.bashrc
source ~/.bashrc        

Windows (PowerShell):

[System.Environment]::SetEnvironmentVariable("API_KEY", "your_api_key", [System.EnvironmentVariableTarget]::User)        

Your app can then read it using:

Python: os.getenv("API_KEY")
Node.js: process.env.API_KEY
C# (.NET): Environment.GetEnvironmentVariable("API_KEY")        

Step 3: Add a Pre-Commit Hook to Stop Secret Commits

Git pre-commit hooks block secrets before they reach your repository.

Setting Up a Git Pre-Commit Hook (Works on Mac, Linux, Windows WSL, or Git Bash)

1. Navigate to Your Repository

cd /path/to/your/repository        

2. Create the Hooks Directory (if not exists)

mkdir -p .git/hooks        

3. Create the Pre-Commit Hook File

nano .git/hooks/pre-commit        

Or for Windows (PowerShell):

New-Item -Path .git/hooks/pre-commit -ItemType File        

4. Copy and Paste the Script

#!/bin/sh

SECRET_PATTERN='(AWS|API|SECRET|TOKEN|PASSWORD|PRIVATE|CERT|DB)_?(KEY|TOKEN|SECRET|PWD|PASS|CRED|CERT)'

if git diff --cached | grep -E "${SECRET_PATTERN}"; then
  echo "? Secret detected! Commit rejected."
  exit 1
fi        

5. Save and Exit

If you're using nano, press CTRL + X, then Y, and Enter to save.

6. Make the Hook Executable

chmod +x .git/hooks/pre-commit        

? Now, if you try to commit a secret, Git will reject it!


Step 4: Scan Repositories for Secrets

If secrets might already be in your repo, scan it using:

Using GitLeaks (Cross-Platform)

# Install GitLeaks on Mac & Linux

curl -sSfL https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks-linux-amd64 -o gitleaks

chmod +x gitleaks && sudo mv gitleaks /usr/local/bin/        

# Windows (PowerShell - Run as Administrator)

iwr -useb https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks-windows-amd64.exe -OutFile gitleaks.exe        

Now, scan your repo:

gitleaks detect --verbose --redact        

? If secrets are found, remove them immediately!


Step 5: Remove Secrets from Git History

If a secret was already committed, removing it from code is NOT enough! It still exists in Git history.

Use BFG Repo-Cleaner to remove secrets safely:

bfg --delete-files secret.json        

Or rewrite history for API keys:

bfg --replace-text banned-words.txt        

?? Don't forget to force push:

git push --force        

? This removes secrets from history while keeping commits intact.


Step 6: Automate Secret Scanning in GitHub and Azure DevOps

To enforce security in CI/CD pipelines, use GitLeaks in GitHub Actions and Azure DevOps Pipelines.

GitHub Actions:

Create .github/workflows/secret-scan.yml

name: Secret Scanning
on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Run GitLeaks
        run: |
          curl -sSfL https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks-linux-amd64 -o gitleaks
          chmod +x gitleaks && sudo mv gitleaks /usr/local/bin/
          gitleaks detect --verbose --redact --exit-code 1        


Azure DevOps Pipeline:

Create azure-pipelines.yml in root directory

trigger:
  branches:
    include:
      - main
      - develop
pool:
  vmImage: 'ubuntu-latest'
steps:
  - script: |
      curl -sSfL https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks-linux-amd64 -o gitleaks
      chmod +x gitleaks && sudo mv gitleaks /usr/local/bin/
      gitleaks detect --verbose --redact --exit-code 1        

AWS DevOps Pipeline:

Create buildspec.yml in root directory of repository

version: 0.2
phases:
  install:
    runtime-versions:
      golang: latest
    commands:
      - echo "Installing GitLeaks..."
      - curl -sSfL https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks-linux-amd64 -o gitleaks
      - chmod +x gitleaks && mv gitleaks /usr/local/bin/

  build:
    commands:
      - echo "Running GitLeaks scan..."
      - gitleaks detect --verbose --redact --exit-code 1        

? This ensures secrets never reach production!


Summary

  1. DO NOT hardcode API keys or passwords. Use environment variables.
  2. DO NOT commit .env or sensitive config files. Add them to .gitignore.
  3. DO use pre-commit hooks to block secrets before they reach Git.
  4. DO scan your repo with GitLeaks regularly.
  5. DO integrate secret scanning into CI/CD pipelines.
  6. DO keep a manual way to pass the build even if Gitleaks gives error, because sometimes it might raise false alarm

要查看或添加评论,请登录

Amjad Hossain的更多文章

社区洞察

其他会员也浏览了