Git and Version Control for Security Engineers
TL;DR: Git is essential for security engineers - you’ll review code for vulnerabilities, hunt for exposed secrets, collaborate with development teams, and maintain your own security tools. Understanding Git deeply helps you both attack (find leaked credentials) and defend (secure development workflows).
Table of Contents
Open Table of Contents
- Quick Reference
- Why Git Matters for Security
- Git Core Concepts
- Secure Code Review Basics
- Secrets Management Mistakes
- Real-World Git Breach Examples
- Using GitHub as Security Portfolio
- Usage
- Example Output
- Security Considerations
- Contributing
- License
- Hands-On Lab
- Interview Questions & Answers
- Glossary
- What’s Next
Quick Reference
Essential Git Commands
| Command | Purpose | Security Use Case |
|---|---|---|
git clone | Copy repository | Get code for review |
git log | View commit history | Find when vulnerability introduced |
git diff | Compare changes | Review security fixes |
git blame | Line-by-line history | Find who introduced issue |
git show | Show commit details | Examine specific changes |
git grep | Search codebase | Find hardcoded secrets |
git log -S | Search commit content | Find removed secrets |
git reflog | Local history | Recover “deleted” data |
git stash | Save changes temporarily | Preserve work during review |
Security-Focused Git Commands
# Search for secrets in history
git log -p -S "password" --all
# Find all commits by author
git log --author="developer@company.com"
# Show file history
git log --follow -p -- path/to/file
# Find when line was added
git log -S "API_KEY" --source --all
# Search all branches for string
git grep "secret" $(git rev-list --all)
# Show deleted files
git log --diff-filter=D --summary
# 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
Why Git Matters for Security
Security Engineers Use Git Daily
┌─────────────────────────────────────────────────────────────┐
│ HOW SECURITY ENGINEERS USE GIT │
├─────────────────┬─────────────────┬─────────────────────────┤
│ OFFENSIVE │ DEFENSIVE │ DEVELOPMENT │
├─────────────────┼─────────────────┼─────────────────────────┤
│ • Hunt leaked │ • Code review │ • Security tools │
│ credentials │ • PR approvals │ • Automation scripts │
│ • Find vulns │ • Pre-commit │ • Config management │
│ in history │ hooks │ • Documentation │
│ • Recon via │ • Branch │ • Collaborate with │
│ public repos │ protection │ dev teams │
└─────────────────┴─────────────────┴─────────────────────────┘
Real Security Workflows
1. Vulnerability Assessment
# Clone application for security review
git clone https://github.com/company/webapp.git
cd webapp
# Search for dangerous functions
git grep -n "eval(" --include="*.js"
git grep -n "exec(" --include="*.py"
git grep -n "system(" --include="*.php"
2. Incident Investigation
# Find when vulnerable code was introduced
git log -S "vulnerable_function" --oneline
# See who made the change
git blame src/auth.py
# Compare before and after fix
git diff abc123..def456 -- src/auth.py
3. Secret Hunting
# Search for hardcoded credentials
git grep -i "password\|secret\|api_key\|token"
# Check commit history for secrets
git log -p | grep -i "aws_\|password\|secret"
Git Core Concepts
The Three States
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Working │ │ Staging │ │ Local │
│ Directory │ ──► │ Area │ ──► │ Repo │
│ │ add │ (Index) │commit│ (.git) │
└─────────────┘ └─────────────┘ └─────────────┘
│
│ push
▼
┌─────────────┐
│ Remote │
│ Repo │
│ (GitHub) │
└─────────────┘
Understanding Commits
Each commit contains:
- Snapshot of all tracked files
- Metadata (author, date, message)
- Parent reference (previous commit)
- SHA-1 hash (unique identifier)
# Anatomy of a commit
git show abc1234
# Output:
commit abc1234def5678...
Author: developer <dev@company.com>
Date: Mon Jan 15 10:30:00 2024
Fix authentication bypass vulnerability
diff --git a/src/auth.py b/src/auth.py
...
Branches and Merging
# Create security-fix branch
git checkout -b security/fix-sqli
# Make changes and commit
git add .
git commit -m "Fix SQL injection in login form"
# Push to remote
git push -u origin security/fix-sqli
# Create pull request for review
# (done on GitHub/GitLab)
Important Security Concept: Git Never Forgets
Even “deleted” data persists in Git history!
# Secret committed then deleted
echo "API_KEY=supersecret123" > config.txt
git add config.txt && git commit -m "Add config"
rm config.txt
git add config.txt && git commit -m "Remove config"
# Secret is STILL in history!
git log -p | grep "API_KEY"
# Output: API_KEY=supersecret123
This is why rotating exposed credentials is mandatory, not optional.
Secure Code Review Basics
What to Look For
| Vulnerability | Code Patterns to Search |
|---|---|
| SQL Injection | "SELECT * FROM " +, .format(), f-strings in queries |
| Command Injection | exec(), system(), subprocess.call(shell=True) |
| XSS | innerHTML, .html(), dangerouslySetInnerHTML |
| Path Traversal | open(user_input), ../ handling |
| Hardcoded Secrets | password =, api_key =, secret = |
| Insecure Deserialization | pickle.loads(), yaml.load(), unserialize() |
| Weak Crypto | MD5, SHA1 for passwords, ECB mode |
Code Review Checklist
## Security Code Review Checklist
### Authentication & Authorization
- [ ] No hardcoded credentials
- [ ] Passwords properly hashed (bcrypt/argon2)
- [ ] Session tokens are secure random
- [ ] Authorization checks on all endpoints
- [ ] MFA implementation if applicable
### Input Validation
- [ ] All user input validated
- [ ] Parameterized queries (no string concat for SQL)
- [ ] Output encoding for XSS prevention
- [ ] File upload restrictions
### Cryptography
- [ ] No weak algorithms (MD5, SHA1, DES)
- [ ] Keys not hardcoded
- [ ] Proper key management
- [ ] TLS enforced for sensitive data
### Error Handling
- [ ] No sensitive data in error messages
- [ ] Proper exception handling
- [ ] Logging without sensitive data
### Dependencies
- [ ] No known vulnerable dependencies
- [ ] Dependencies from trusted sources
- [ ] Locked versions (not floating)
Git Commands for Code Review
# Review specific pull request changes
git fetch origin pull/123/head:pr-123
git checkout pr-123
git diff main...pr-123
# See only security-relevant files
git diff main...pr-123 -- "*.py" "*.js"
# Find all changes to authentication code
git log --oneline --all -- "*auth*" "*login*" "*session*"
# Review changes by a specific developer
git log --author="newdev@company.com" -p
# Find recently modified files (attack surface changes)
git diff --stat HEAD~10
# Generate diff for external review
git diff main...feature-branch > review.patch
Automated Security Scanning in Git
Pre-commit hooks can catch issues before they’re committed:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: detect-private-key
- id: detect-aws-credentials
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
- repo: https://github.com/PyCQA/bandit
rev: 1.7.5
hooks:
- id: bandit
args: ["-r", "src/"]
Install and run:
pip install pre-commit
pre-commit install
pre-commit run --all-files
Secrets Management Mistakes
Common Ways Secrets Get Exposed
| Mistake | Example | Impact |
|---|---|---|
| Committed to repo | password = "admin123" | Permanent in history |
| In config files | config.yml with API keys | Exposed in public repos |
| Environment file committed | .env with secrets | Easy to find |
| Debug code left in | print(f"Token: {token}") | Logged or exposed |
| Test credentials | Hardcoded in test files | Often real creds |
| Docker images | Secrets in Dockerfile | Extractable from layers |
| CI/CD logs | Echo’d in pipeline | Visible in build logs |
Finding Secrets in Git History
# Using git-secrets (AWS tool)
git secrets --install
git secrets --scan-history
# Using trufflehog
trufflehog git https://github.com/company/repo --only-verified
# Using gitleaks
gitleaks detect --source . --verbose
# Manual search patterns
git log -p | grep -iE "(password|secret|api_key|token|credential).*="
# Search for AWS keys
git log -p | grep -E "AKIA[0-9A-Z]{16}"
# Search for private keys
git log -p | grep -E "-----BEGIN (RSA|OPENSSH|DSA|EC) PRIVATE KEY-----"
What to Do When Secrets Are Exposed
Immediate Actions:
- Rotate the credential immediately - This is the priority
- Revoke the exposed token/key
- Review access logs for unauthorized use
- Remove from history (optional, see below)
- Implement prevention (pre-commit hooks)
Removing Secrets from History (if needed):
# Using BFG Repo Cleaner (recommended)
bfg --delete-files config.yml
bfg --replace-text passwords.txt
# Then force push
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push --force --all
⚠️ Warning: Force pushing rewrites history and affects all collaborators. Rotation is still required because:
- Forks may retain the secret
- Clone caches may exist
- The secret may be logged elsewhere
Secrets Management Best Practices
# 1. Use environment variables
export DATABASE_PASSWORD="secret"
# In code: os.environ.get('DATABASE_PASSWORD')
# 2. Use .gitignore properly
echo ".env" >> .gitignore
echo "*.pem" >> .gitignore
echo "secrets/" >> .gitignore
# 3. Use git-crypt for encrypted secrets
git-crypt init
git-crypt add-gpg-user security@company.com
# Secrets are encrypted in repo, decrypted locally
# 4. Use external secret managers
# AWS Secrets Manager, HashiCorp Vault, Azure Key Vault
Secret Detection Patterns
# .gitleaks.toml - Custom rules
[[rules]]
description = "AWS Access Key"
regex = '''AKIA[0-9A-Z]{16}'''
tags = ["aws", "key"]
[[rules]]
description = "Generic Password"
regex = '''(?i)(password|passwd|pwd)\s*[=:]\s*['"][^'"]{8,}['"]'''
tags = ["password"]
[[rules]]
description = "Private Key"
regex = '''-----BEGIN (RSA|OPENSSH|DSA|EC) PRIVATE KEY-----'''
tags = ["key", "private"]
[[rules]]
description = "Slack Token"
regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})'''
tags = ["slack", "token"]
Real-World Git Breach Examples
Case Study 1: Uber (2016)
What Happened:
- Developers committed AWS credentials to a private GitHub repo
- Attackers accessed the repo (unclear how - possibly credential stuffing)
- Used AWS keys to access S3 bucket with 57 million user records
Lessons:
- Private repos aren’t secure if credentials are weak
- Secrets in Git history persist even after deletion
- Regular secret scanning is essential
Case Study 2: Samsung (2019)
What Happened:
- Developers committed source code with API keys to public GitLab
- Included AWS credentials, private keys, and internal tokens
- Discovered by security researcher via public search
Lessons:
- Verify repo visibility before pushing
- Use pre-commit hooks to prevent secret commits
- Regular audits of public repository presence
Case Study 3: Twitch (2021)
What Happened:
- Internal Git server misconfiguration exposed entire codebase
- 125GB of data including source code and internal tools
- Streamer payout information leaked
Lessons:
- Git server security is critical
- Access controls must be regularly audited
- Defense in depth (even internal repos need security)
Case Study 4: Toyota (2022)
What Happened:
- Access key for customer data was in public GitHub repo for 5 years
- 296,019 customer records potentially exposed
- Discovered during routine security audit
Lessons:
- Long exposure windows are common
- Automated scanning should run continuously
- Historical commits need scanning too
Prevention Framework
┌─────────────────────────────────────────────────────────────┐
│ SECRET EXPOSURE PREVENTION │
├─────────────────────────────────────────────────────────────┤
│ LAYER 1: DEVELOPER │
│ • Education on secret handling │
│ • IDE plugins for secret detection │
│ • Pre-commit hooks │
├─────────────────────────────────────────────────────────────┤
│ LAYER 2: REPOSITORY │
│ • Branch protection rules │
│ • Required code reviews │
│ • GitHub secret scanning │
├─────────────────────────────────────────────────────────────┤
│ LAYER 3: CI/CD │
│ • Automated secret scanning │
│ • Block merges on detection │
│ • Scan dependencies │
├─────────────────────────────────────────────────────────────┤
│ LAYER 4: MONITORING │
│ • Continuous repo scanning │
│ • Public exposure monitoring │
│ • Credential usage alerting │
└─────────────────────────────────────────────────────────────┘
Using GitHub as Security Portfolio
Why GitHub Matters for Your Career
Hiring managers look at GitHub profiles to evaluate:
- Code quality and security awareness
- Project complexity and completion
- Communication (README, issues, PRs)
- Collaboration skills
- Continuous learning
What to Include
Security Tools You’ve Built:
## Example Projects
1. **log-analyzer** - Python tool for parsing security logs
- Detects brute force attacks
- Generates IOC reports
- Integrates with SIEM
2. **vuln-scanner** - Automated vulnerability scanner
- Checks for common misconfigs
- Generates remediation reports
- CI/CD integration
3. **incident-response-scripts** - IR automation
- Memory acquisition
- Log collection
- Timeline generation
Write-ups and Documentation:
- CTF solutions (without spoilers for active challenges)
- Security research findings
- Tool tutorials and guides
Professional README Template
# Project Name
## Overview
Brief description of what this tool does and why it's useful.
## Security Features
- What security problems does it solve?
- What threats does it mitigate?
## Installation
```bash
git clone https://github.com/you/project.git
pip install -r requirements.txt
Usage
python scanner.py --target example.com
Example Output
Show what users can expect.
Security Considerations
- How to use this tool responsibly
- Legal/ethical considerations
- Limitations
Contributing
How others can contribute.
License
MIT/Apache/etc.
### GitHub Profile Best Practices
```markdown
# Your Name | Security Engineer
## About
Passionate about application security, penetration testing, and
building security tools. Currently focused on cloud security.
## Certifications
- OSCP
- AWS Security Specialty
## Current Projects
- Building detection rules for cloud environments
- Contributing to OWASP projects
## Contact
- LinkedIn: /in/yourname
- Blog: yourblog.com
What NOT to Include
- ❌ Actual exploits for unpatched vulnerabilities
- ❌ Client/employer confidential code
- ❌ Malware (even for research without clear context)
- ❌ Credentials (even fake ones that look real)
- ❌ Personal data from security research
Hands-On Lab
Lab: Review a Vulnerable Code Repository
Objective: Practice finding security issues using Git.
Setup:
# Clone a deliberately vulnerable repo
git clone https://github.com/OWASP/WebGoat.git
cd WebGoat
Tasks:
Task 1: Find Hardcoded Secrets
# Search for password patterns
git grep -n -i "password"
# Search for API keys
git grep -n -E "(api_key|apikey|api-key)"
# Search for tokens
git grep -n -i "token"
Task 2: Find Dangerous Functions
# SQL injection patterns
git grep -n "executeQuery.*+"
git grep -n "createQuery.*+"
# Command injection patterns
git grep -n "Runtime.getRuntime().exec"
git grep -n "ProcessBuilder"
Task 3: Review Git History for Secrets
# Search all history for secrets
git log -p | grep -i "password"
# Use git log -S to find when secrets were added
git log -S "password" --oneline
Task 4: Analyze a Specific Commit
# Find a security-related commit
git log --grep="security\|vulnerability\|fix" --oneline
# Analyze the fix
git show <commit-hash>
# Was it a complete fix?
Deliverables:
- List of found security issues
- Git commands used
- Recommendations for remediation
Interview Questions & Answers
Basic Questions
Q1: Why is Git knowledge important for security engineers?
Strong Answer: “Git is central to security work in several ways:
Offensive: I hunt for leaked credentials in public repos, analyze code for vulnerabilities, and use commit history to understand application evolution.
Defensive: I review code changes for security issues, implement pre-commit hooks to prevent secret leaks, and set up branch protection for security controls.
Development: I maintain security tools, collaborate with developers on fixes, and document security findings.
Understanding Git deeply helps me find issues others miss - like secrets that were committed and then ‘deleted’ but still exist in history.”
Q2: A developer accidentally committed an API key. What do you do?
Strong Answer: “I follow this priority order:
Immediately rotate the key - This is the most critical step. The key should be revoked and regenerated regardless of anything else.
Check for unauthorized use - Review API logs for the exposed key to detect any suspicious activity during the exposure window.
Remove from history - Use BFG Repo Cleaner or git filter-branch to remove the secret from all commits, then force push.
Notify affected parties - If the key provided access to sensitive data, follow incident response procedures.
Implement prevention - Add pre-commit hooks with detect-secrets or similar tools to prevent future occurrences.
The key point is that removing from history is necessary but not sufficient - rotation is mandatory because the secret may exist in forks, caches, or logs.”
Q3: How do you perform a security code review using Git?
Strong Answer: “I follow a systematic approach:
Understand the change scope:
git diff main...feature-branch --statFocus on security-sensitive files:
- Authentication/authorization code
- Input handling
- Database queries
- Crypto implementation
Search for dangerous patterns:
git grep -n 'eval\|exec\|system' -- '*.py'Check the history:
- Was vulnerable code introduced and ‘fixed’ before?
- Who made the changes and do they have security training?
Verify against security checklist:
- Input validation, output encoding, authentication, etc.
Document findings with specific line numbers and remediation recommendations.”
Intermediate Questions
Q4: How would you find secrets that were committed and deleted in a repo’s history?
Strong Answer: “Several methods:
Using git log with search:
git log -p -S 'password' --all git log -p | grep -iE '(api_key|secret|password)'Using specialized tools:
trufflehog git --repo-path . --include-paths '*' gitleaks detect --source . --verboseManual investigation:
# Find all commits that touched sensitive files git log --all --full-history -- '*config*' '*.env' # Check reflog for local history git reflogThe key insight is that Git stores every version of every file. Even if a secret is deleted in the latest commit, all previous versions persist in the repository’s history until explicitly purged.”
Q5: Explain Git branch protection and why it matters for security.
Strong Answer: “Branch protection rules enforce security controls on important branches like main or production.
Key protections include:
- Required reviews - At least one (ideally two) approvers before merge, ensuring security review
- Required status checks - CI/CD must pass, including security scans
- No force pushes - Prevents history rewriting that could hide malicious changes
- Signed commits - Ensures commit authenticity
- CODEOWNERS - Security team must approve changes to sensitive files
Security benefits:
- Prevents direct commits of malicious code
- Ensures security scanning before merge
- Creates audit trail of all changes
- Reduces risk of credential leaks reaching production
I’ve seen environments where missing branch protection allowed attackers to push directly to main after compromising a developer account.”
Advanced Questions
Q6: How would you set up a secure Git workflow for a development team?
Strong Answer: “I’d implement defense in depth:
Developer Level:
- Pre-commit hooks for secret detection (detect-secrets, git-secrets)
- IDE security plugins
- Security training on secure coding
Repository Level:
- Branch protection on main/release branches
- Required code reviews with security-trained reviewers
- CODEOWNERS file for security-sensitive paths
- GitHub secret scanning enabled
CI/CD Level:
- SAST scanning (Semgrep, SonarQube)
- Dependency scanning (Dependabot, Snyk)
- Secret scanning in pipeline
- Container image scanning
- Block merge on critical findings
Monitoring:
- Audit logs for repository access
- Alerts on branch protection changes
- Regular scanning of all repos including history
- Public exposure monitoring
The goal is catching issues as early as possible while not blocking developer productivity excessively.”
Q7: A red team assessment found that your company has secrets exposed in public GitHub repos. How do you respond and prevent recurrence?
Strong Answer: “I’d handle this as a security incident:
Immediate Response (Day 1):
- Identify all exposed secrets across all repos
- Rotate every exposed credential immediately
- Review access logs for signs of abuse
- Make repos private if appropriate
Short-term (Week 1):
- Run comprehensive secret scanning on all repos (including history)
- Remove secrets from Git history using BFG
- Implement pre-commit hooks organization-wide
- Enable GitHub secret scanning and push protection
Long-term (Month 1+):
- Deploy organization-wide Git security policy
- Mandatory security training for all developers
- Regular automated scanning of all repositories
- Monitor for public exposure continuously
- Implement secret management solution (Vault, AWS Secrets Manager)
Metrics to track:
- Number of secrets detected over time
- Mean time to remediation
- Developer compliance with pre-commit hooks
The goal is making secret exposure a rare exception rather than a regular occurrence.”
Glossary
| Term | Definition |
|---|---|
| Commit | Snapshot of repository at a point in time |
| Branch | Independent line of development |
| Merge | Combining changes from different branches |
| Pull Request (PR) | Request to merge changes with review |
| Fork | Personal copy of a repository |
| Clone | Local copy of a repository |
| SHA/Hash | Unique identifier for a commit |
| HEAD | Pointer to current commit |
| Reflog | Log of all reference updates (local) |
| Force Push | Overwrite remote history (dangerous) |
| Pre-commit Hook | Script that runs before each commit |
| CODEOWNERS | File defining required reviewers |
What’s Next
Continue building your security engineering skills:
- Securing CI/CD Pipelines - Apply Git security in pipelines
- Bash and PowerShell for Security - Automate Git security tasks
- Linux Hardening - Secure your Git servers
Questions or feedback? Open an issue on GitHub.