Git Secrets and Preventing Credential Leaks Tools and Best Practices
Learn how to prevent credential leaks in Git using pre-commit hooks, secret scanning tools, and what to do if secrets are accidentally committed.
Git Secrets and Preventing Credential Leaks
Accidentally committing secrets (API keys, passwords, .env files) to Git is one of the most common security incidents. This guide covers prevention and response.
How Credentials Leak
- Committing .env Adding .env to Git accidentally
- Hardcoded secrets Putting API keys directly in code
- Config files Putting secrets in config.js instead of .env
- Test files Using real credentials in tests
- Comments Leaving credentials in code comments
- Git history Secrets remain in history even after removal
Prevention 1: .gitignore
# .gitignore .env .env.local .env.*.local # Also ignore common secret files *.pem *.key credentials.json service-account.json
Prevention 2: Pre-commit Hooks with git-secrets
# Install git-secrets brew install git-secrets # Mac sudo apt install git-secrets # Ubuntu # Set up for your repo cd your-project git secrets --install git secrets --register-aws git secrets --add "JWT_SECRET=.*" git secrets --add "MONGODB_URI=.*"
Now every commit is scanned for secrets. If found, the commit is blocked.
Prevention 3: husky + lint-staged
npm install --save-dev husky lint-staged npx husky install npx husky add .husky/pre-commit "npx lint-staged"
// package.json { "lint-staged": { "*.js": [ "node scripts/check-secrets.js" ] } }
// scripts/check-secrets.js const fs = require("fs"); const { execSync } = require("child_process"); const files = process.argv.slice(2); const secretPatterns = [ /AKIA[0-9A-Z]{16}/, // AWS access key /mongodb://.*:.*@/, // MongoDB URI with credentials /JWT_SECRET=.{10,}/, // JWT secret /api[_-]?key.{0,10}=.{10,}/i, // API key ]; let hasSecrets = false; files.forEach(file => { const content = fs.readFileSync(file, "utf-8"); secretPatterns.forEach(pattern => { if (pattern.test(content)) { console.error(`Potential secret found in ${file}`); hasSecrets = true; } }); }); if (hasSecrets) { console.error("Commit blocked: Potential secrets detected"); process.exit(1); }
Prevention 4: GitHub Secret Scanning
GitHub automatically scans for known secret formats (AWS keys, Stripe keys, etc.) and alerts you. Enable in:
- Repository → Settings → Code security and analysis → Secret scanning → Enable
Prevention 5: Environment-based Configuration
Never put secrets in code:
// WRONG const apiKey = "sk_live_abc123"; // RIGHT const apiKey = process.env.STRIPE_API_KEY;
What to Do If Secrets Are Committed
Step 1: Rotate the Secret Immediately
The secret is compromised. Generate a new one:
# Generate new JWT secret node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" # Update .env with the new secret nano .env
Step 2: Remove from Git History
# Remove .env from all commits git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch .env" \ --prune-empty --tag-name-filter cat -- --all # Or use BFG Repo-Cleaner bfg --delete-files .env bfg --replace-text passwords.txt git reflog expire --expire=now --all git gc --prune=now --aggressive
Step 3: Force Push
git push origin --force --all git push origin --force --tags
Warning: Force push rewrites history. Coordinate with your team.
Step 4: Audit for Unauthorized Access
- Check AWS CloudTrail for unauthorized API calls
- Check database access logs
- Check application logs for suspicious activity
- Monitor for unusual behavior
Tools for Secret Scanning
| Tool | Type | Price |
|---|---|---|
| git-secrets | Pre-commit hook | Free |
| truffleHog | Scanner | Free |
| GitGuardian | SaaS | Free tier |
| GitHub Secret Scanning | GitHub feature | Free (public repos) |
| Snyk | SaaS | Free tier |
| BFG Repo-Cleaner | History cleaner | Free |
The Takeaway
Prevent credential leaks with .gitignore, pre-commit hooks (git-secrets, husky), and GitHub Secret Scanning. Never hardcode secrets always use environment variables. If secrets are committed, rotate them immediately, remove from Git history with git filter-branch or BFG, force push, and audit for unauthorized access.
Add .env to .gitignore, use pre-commit hooks with git-secrets or husky to scan for secrets before each commit, enable GitHub Secret Scanning, and never hardcode secrets in code always use process.env. Use tools like truffleHog or GitGuardian for ongoing scanning.
Rotate the secret immediately (it's compromised). Remove from Git history with git filter-branch or BFG Repo-Cleaner. Force push the cleaned history. Audit AWS CloudTrail and database logs for unauthorized access. Notify your team and update all affected services with new secrets.
git-secrets is a pre-commit hook tool that scans your staged changes for known secret patterns (AWS keys, custom patterns) before each commit. If a secret is found, the commit is blocked. Install with brew install git-secrets, then git secrets --install in your repo.
Use git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch .env' --prune-empty --tag-name-filter cat -- --all. Or use BFG Repo-Cleaner: bfg --delete-files .env. Then git reflog expire --expire=now --all, git gc --prune=now --aggressive, and force push.
Yes, GitHub Secret Scanning automatically scans for known secret formats (AWS keys, Stripe keys, GitHub tokens, etc.) and alerts you. Enable it in Repository → Settings → Code security and analysis → Secret scanning. It's free for public repos and available on GitHub Enterprise for private repos.
Ready to master Node.js completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master Node.js
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

