DEV Community

Alex Spinov
Alex Spinov

Posted on

Your .env File Is Probably in Your Git History (Here's How to Check)

You added .env to .gitignore. You deleted the committed version. You think you're safe.

You're probably not.

Git remembers everything. That .env file you committed 6 months ago — with your database password, Stripe keys, and AWS credentials — is still in your git history. Anyone who clones your repo can find it in seconds.

How Bad Is This?

GitGuardian's 2024 State of Secrets report found:

  • 12.8 million new secrets leaked on GitHub in one year
  • 39% of scanned repos contained at least one secret
  • 90% of leaked secrets remain valid for 5+ days after detection

Check Your Repo in 30 Seconds

Run this in your project directory:

# Check if .env was ever committed
git log --all --diff-filter=A --name-only -- '.env*' | head -20
Enter fullscreen mode Exit fullscreen mode

If you see output — your secrets are in the history.

The Deeper Check

# Find ALL secret-like files ever committed
git log --all --diff-filter=A --name-only --pretty=format: -- \
  '*.env' '*.env.*' '*.pem' '*.key' 'credentials*' 'secrets*' \
  | sort -u | grep -v '^$'
Enter fullscreen mode Exit fullscreen mode

Automated Scanner

I built a Python tool that does a comprehensive check:

import re, subprocess
from pathlib import Path

SECRET_PATTERNS = {
    'AWS Key': r'AKIA[0-9A-Z]{16}',
    'GitHub Token': r'(ghp|gho)_[A-Za-z0-9_]{36,}',
    'Stripe Key': r'sk_live_[0-9a-zA-Z]{24,}',
    'Slack Token': r'xox[bpors]-[0-9A-Za-z\-]{10,}',
    'Generic Secret': r'(?i)(secret|password)\s*[=:]\s*[^\s]{8,}',
    'Database URL': r'(?i)(postgres|mysql|mongodb)://[^:]+:[^@]+@',
}

def scan_env_file(filepath):
    issues = []
    with open(filepath) as f:
        for i, line in enumerate(f, 1):
            for name, pattern in SECRET_PATTERNS.items():
                if re.search(pattern, line):
                    issues.append(f"  Line {i}: {name} detected")
    return issues

def check_gitignore():
    gi = Path('.gitignore')
    if not gi.exists():
        return "No .gitignore found!"
    return ".env in .gitignore" if '.env' in gi.read_text() else ".env NOT in .gitignore!"

# Run it
print(check_gitignore())
for env_file in Path('.').glob('.env*'):
    issues = scan_env_file(env_file)
    if issues:
        print(f"\n{env_file}: {len(issues)} secrets found")
        for issue in issues:
            print(issue)
Enter fullscreen mode Exit fullscreen mode

For the full version with git history scanning and CI/CD integration, check out env-secrets-checker on GitHub.

If You Find Secrets in Your History

Don't panic. But do act fast:

Step 1: Rotate ALL exposed credentials

Before cleaning the git history, rotate every key that was exposed. Assume they've been compromised.

Step 2: Use git-filter-repo (NOT filter-branch)

# Install
pip install git-filter-repo

# Remove .env from entire history
git filter-repo --invert-paths --path .env --force

# Force push (this rewrites history for everyone)
git push --force --all
Enter fullscreen mode Exit fullscreen mode

Step 3: Prevent future leaks

Add to .gitignore:

.env
.env.*
!.env.example
Enter fullscreen mode Exit fullscreen mode

Add a pre-commit hook:

#!/bin/sh
if git diff --cached --name-only | grep -q '\.env'; then
    echo "Blocked: .env file in staged changes"
    exit 1
fi
Enter fullscreen mode Exit fullscreen mode

Best Practices

  1. Never put real secrets in .env — use a secrets manager (Vault, AWS SSM, Doppler)
  2. Always have .env.example with placeholder values checked in
  3. Use pre-commit hooks to catch .env before it's committed
  4. Run automated scans in CI/CD pipeline
  5. Rotate keys regularly — even without a breach

The Checklist

  • [ ] Is .env in .gitignore?
  • [ ] Does .env.example exist with placeholders?
  • [ ] Is there a pre-commit hook blocking .env commits?
  • [ ] Have you checked git history for past leaks?
  • [ ] Are all detected secrets rotated?

Run that git log command on your repos today. You might be surprised what you find.

For a comprehensive scan, try env-secrets-checker — checks .env files, git history, config files, and Docker files in one command.

Follow for more security and DevOps content.

Top comments (0)