Secrets in Git History
Deleting a secret from code and committing the removal does NOT remove the secret from git history. Every version of every file is preserved in .git/objects. A git clone gives anyone the complete history, including every password, API key, and private key ever committed.
The Git History Problem
Developers frequently commit credentials during development, then remove them in a later commit. They believe the secret is gone — but it persists in git history forever. Tools like git log -p, trufflehog, and simple grep can extract these historical secrets. Force-pushing or rebasing local branches does not affect remote history in GitHub/GitLab.
Real-World Impact
Uber's 2016 breach (57M records) started with AWS credentials found in a GitHub repository. The credentials had been committed, then removed — but were still in git history. Attackers used them to access an S3 bucket with rider and driver data. Similar incidents have affected Samsung, Toyota, and thousands of startups.
Precogs AI Git History Scanning
Precogs AI scans every commit in git history — not just the current HEAD. We analyze diffs, blob objects, and deleted branches for credential patterns. Our scanning covers: full commit history, pull request branches, stash entries, and reflog entries that may contain secrets in orphaned commits.
Attack Scenario: The BGH (Buried Git History) Extraction
An enterprise mandates moving all repositories from an internal GitLab server to a cloud-hosted GitHub Enterprise organization.
During the migration, developers run `git push --all` to transfer the repositories.
The codebase currently passes all modern Static Analysis (SAST) and secret scanning checks.
However, an attacker who recently acquired read access to the GitHub org runs a tool like `trufflehog` or `gitleaks` configured to scan deep history.
The tool finds an RSA Private Key that was committed 4 years ago for a staging environment, but the key is still actively used in production.
The attacker extracts the old commit blob, imports the RSA key, and achieves root access to the production application servers.
Real-World Code Examples
Secret Persistence in Git Objects
Git is an immutable Merkle tree. Every change creates a new snapshot object. Deleting a secret in a subsequent commit does not erase the historical snapshot. Anyone who can clone the repository can traverse the entire historical object database (`.git/objects`) to extract the buried credentials.
Detection & Prevention Checklist
- ✓Configure Secret Scanners to scan `--all` branches and the full depth of commit history during initial repository onboarding
- ✓Execute continuous, incremental scans specifically targeting the `.git/objects` directory differences on every pull request push
- ✓Develop an incident response playbook specifically detailing how to use `git filter-repo` to cleanly rewrite enterprise history without destroying developer workflows
- ✓Always operate under the assumption that if a secret touches a Git index for even a millisecond, it must be considered burnt and requires immediate cryptographic rotation
- ✓Understand that force-pushing removes commits from active tree logic but leaves "orphaned commits" in the reflog. Clean up remote GC (Garbage Collection) explicitly
How Precogs AI Protects You
Precogs AI scans complete git history — every commit, branch, stash, and reflog entry — detecting credentials, API keys, and private keys that were committed and later removed but still exist in .git objects.
Start Free ScanCan secrets be recovered from git history?
Yes — every file version is preserved in .git objects. Deleting a secret and committing the removal does NOT remove it from history. Precogs AI scans complete git history including deleted branches, stashes, and reflog entries.
Scan for Secrets in Git History Issues
Precogs AI automatically detects secrets in git history vulnerabilities and generates AutoFix PRs.