GIT SECURITY & SECRETS HYGIENE
PREVENTING SECRET COMMITS#
# .gitignore essentials .env .env.* *.pem *.key *.p12 *.pfx credentials.json secrets.yaml *_rsa *_ecdsa *_ed25519 *.keystore config/database.yml # Global gitignore git config --global core.excludesfile ~/.gitignore_global
PRE-COMMIT HOOKS#
# Install pre-commit framework
pip install pre-commit
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: detect-private-key
- id: check-added-large-files
# Install hooks
pre-commit install
# Run on all files
pre-commit run --all-files
SECRET SCANNING TOOLS#
# Gitleaks - scan for secrets gitleaks detect # Scan current repo gitleaks detect --source=/path # Scan specific path gitleaks detect --log-opts="--all" # Scan all branches gitleaks detect -v # Verbose output gitleaks protect # Pre-commit mode gitleaks detect --baseline-path=.gitleaks-baseline.json # With baseline # TruffleHog - deep secret scanning trufflehog git file:///path/to/repo trufflehog github --org=myorg # Scan GitHub org trufflehog --only-verified # Only verified secrets # git-secrets (AWS) git secrets --install # Install in repo git secrets --register-aws # Add AWS patterns git secrets --scan # Scan for secrets git secrets --scan-history # Scan full history
CLEANING SECRETS FROM HISTORY#
# BFG Repo Cleaner (recommended - faster than filter-branch)
# Remove file from all history
bfg --delete-files secrets.env
# Replace text in all history
bfg --replace-text replacements.txt
# replacements.txt: MY_SECRET_KEY==>***REMOVED***
# After BFG
git reflog expire --expire=now --all
git gc --prune=now --aggressive
# git filter-repo (modern replacement for filter-branch)
pip install git-filter-repo
git filter-repo --path secrets.env --invert-paths
git filter-repo --blob-callback '
if b"API_KEY" in blob.data:
blob.data = blob.data.replace(b"actual_key", b"REDACTED")
'
# Force push after cleaning (coordinate with team!)
git push --force --all
git push --force --tags
SIGNED COMMITS#
# GPG signing gpg --full-generate-key gpg --list-secret-keys --keyid-format=long git config --global user.signingkey ABC123DEF456 git config --global commit.gpgsign true git commit -S -m "Signed commit" # SSH signing (Git 2.34+) git config --global gpg.format ssh git config --global user.signingkey ~/.ssh/id_ed25519.pub git config --global commit.gpgsign true # Verify signatures git log --show-signature git verify-commit HEAD git verify-tag v1.0.0
BRANCH PROTECTION#
# GitHub branch protection rules: # - Require pull request reviews # - Require status checks to pass # - Require signed commits # - Require linear history # - Restrict who can push # - Do not allow force pushes # - Do not allow deletions # GitLab protected branches: # Settings > Repository > Protected Branches # - Allowed to merge: Maintainers # - Allowed to push: No one # - Require code owner approval
CREDENTIAL STORAGE#
# Use credential helper (not plaintext!) git config --global credential.helper cache # Cache 15 min git config --global credential.helper 'cache --timeout=3600' # 1 hour git config --global credential.helper osxkeychain # macOS git config --global credential.helper store # INSECURE plaintext # Use SSH keys instead of passwords ssh-keygen -t ed25519 -C "git@example.com" # Use personal access tokens with minimal scopes # GitHub: Settings > Developer Settings > Personal Access Tokens
CI/CD PIPELINE SECURITY#
# Never hardcode secrets in CI files # BAD: # env: # API_KEY: "sk-actual-secret-key" # GOOD: Use CI/CD secret variables # GitHub: Settings > Secrets and Variables > Actions # GitLab: Settings > CI/CD > Variables (masked + protected) # Minimal token permissions # GitHub Actions: permissions: contents: read packages: write # Pin actions to SHA, not tags # BAD: uses: actions/checkout@v4 # GOOD: uses: actions/checkout@abc123def456...
COMMON MISTAKES#
# 1. Committing .env files # 2. Hardcoding API keys in source code # 3. Using git add . or git add -A without reviewing # 4. Storing credentials in git config # 5. Using HTTP instead of SSH for remotes # 6. Not rotating leaked secrets immediately # 7. Assuming private repos are secure # 8. Not using branch protection
GIT SECURITY AUDIT COMMANDS#
# Find large files in history git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sort -k3 -n -r | head -20 # Search for potential secrets in history git log --all -p | grep -iE "(api_key|secret|password|token|aws_access)" | head -20 # Check remote URLs (ensure SSH not HTTP with embedded creds) git remote -v # List all contributors git shortlog -sne --all # Check .git directory permissions ls -la .git/
GIT SECURITY & SECRETS HYGIENE CHEATSHEET
==========================================
Source: https://cheatsheet.johlem.net
PREVENTING SECRET COMMITS
--------------------------
# .gitignore essentials
.env
.env.*
*.pem
*.key
*.p12
*.pfx
credentials.json
secrets.yaml
*_rsa
*_ecdsa
*_ed25519
*.keystore
config/database.yml
# Global gitignore
git config --global core.excludesfile ~/.gitignore_global
PRE-COMMIT HOOKS
-----------------
# Install pre-commit framework
pip install pre-commit
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: detect-private-key
- id: check-added-large-files
# Install hooks
pre-commit install
# Run on all files
pre-commit run --all-files
SECRET SCANNING TOOLS
---------------------
# Gitleaks - scan for secrets
gitleaks detect # Scan current repo
gitleaks detect --source=/path # Scan specific path
gitleaks detect --log-opts="--all" # Scan all branches
gitleaks detect -v # Verbose output
gitleaks protect # Pre-commit mode
gitleaks detect --baseline-path=.gitleaks-baseline.json # With baseline
# TruffleHog - deep secret scanning
trufflehog git file:///path/to/repo
trufflehog github --org=myorg # Scan GitHub org
trufflehog --only-verified # Only verified secrets
# git-secrets (AWS)
git secrets --install # Install in repo
git secrets --register-aws # Add AWS patterns
git secrets --scan # Scan for secrets
git secrets --scan-history # Scan full history
CLEANING SECRETS FROM HISTORY
------------------------------
# BFG Repo Cleaner (recommended - faster than filter-branch)
# Remove file from all history
bfg --delete-files secrets.env
# Replace text in all history
bfg --replace-text replacements.txt
# replacements.txt: MY_SECRET_KEY==>***REMOVED***
# After BFG
git reflog expire --expire=now --all
git gc --prune=now --aggressive
# git filter-repo (modern replacement for filter-branch)
pip install git-filter-repo
git filter-repo --path secrets.env --invert-paths
git filter-repo --blob-callback '
if b"API_KEY" in blob.data:
blob.data = blob.data.replace(b"actual_key", b"REDACTED")
'
# Force push after cleaning (coordinate with team!)
git push --force --all
git push --force --tags
SIGNED COMMITS
--------------
# GPG signing
gpg --full-generate-key
gpg --list-secret-keys --keyid-format=long
git config --global user.signingkey ABC123DEF456
git config --global commit.gpgsign true
git commit -S -m "Signed commit"
# SSH signing (Git 2.34+)
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
# Verify signatures
git log --show-signature
git verify-commit HEAD
git verify-tag v1.0.0
BRANCH PROTECTION
-----------------
# GitHub branch protection rules:
# - Require pull request reviews
# - Require status checks to pass
# - Require signed commits
# - Require linear history
# - Restrict who can push
# - Do not allow force pushes
# - Do not allow deletions
# GitLab protected branches:
# Settings > Repository > Protected Branches
# - Allowed to merge: Maintainers
# - Allowed to push: No one
# - Require code owner approval
CREDENTIAL STORAGE
------------------
# Use credential helper (not plaintext!)
git config --global credential.helper cache # Cache 15 min
git config --global credential.helper 'cache --timeout=3600' # 1 hour
git config --global credential.helper osxkeychain # macOS
git config --global credential.helper store # INSECURE plaintext
# Use SSH keys instead of passwords
ssh-keygen -t ed25519 -C "git@example.com"
# Use personal access tokens with minimal scopes
# GitHub: Settings > Developer Settings > Personal Access Tokens
CI/CD PIPELINE SECURITY
-------------------------
# Never hardcode secrets in CI files
# BAD:
# env:
# API_KEY: "sk-actual-secret-key"
# GOOD: Use CI/CD secret variables
# GitHub: Settings > Secrets and Variables > Actions
# GitLab: Settings > CI/CD > Variables (masked + protected)
# Minimal token permissions
# GitHub Actions:
permissions:
contents: read
packages: write
# Pin actions to SHA, not tags
# BAD: uses: actions/checkout@v4
# GOOD: uses: actions/checkout@abc123def456...
COMMON MISTAKES
---------------
# 1. Committing .env files
# 2. Hardcoding API keys in source code
# 3. Using git add . or git add -A without reviewing
# 4. Storing credentials in git config
# 5. Using HTTP instead of SSH for remotes
# 6. Not rotating leaked secrets immediately
# 7. Assuming private repos are secure
# 8. Not using branch protection
GIT SECURITY AUDIT COMMANDS
-----------------------------
# Find large files in history
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sort -k3 -n -r | head -20
# Search for potential secrets in history
git log --all -p | grep -iE "(api_key|secret|password|token|aws_access)" | head -20
# Check remote URLs (ensure SSH not HTTP with embedded creds)
git remote -v
# List all contributors
git shortlog -sne --all
# Check .git directory permissions
ls -la .git/
Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.