trufflehog: finding and verifying leaked credentials
TruffleHog · AGPL-3.0
trufflehog scans content for credentials and — this is what separates it from every regex-based secret scanner — attempts to verify them against the issuing service. An unverified match is a string that looks like a key. A verified match is a key that works.
Install
# macOS
brew install trufflehog
# Linux
curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh
| sh -s -- -b /usr/local/bin
# Docker
docker run --rm -it trufflesecurity/trufflehog:latest github --repo https://github.com/example/repo Core commands
# a git repo, full history
trufflehog git https://github.com/example/repo --only-verified
# a local checkout
trufflehog filesystem ./src --only-verified
# a whole GitHub org
trufflehog github --org=example --only-verified
# JSON for import
trufflehog git file://./repo --only-verified --json > secrets.jsonl
# S3, with a specific credential profile
trufflehog s3 --bucket=example-assets --only-verified --only-verified is the flag that makes the output reportable. Without it you get thousands of candidate strings; with it you get credentials that authenticated successfully.
Output
{"SourceMetadata":{"Data":{"Git":{"commit":"a3f9...","file":"config/settings.py",
"line":42,"repository":"https://github.com/example/repo"}}},
"DetectorName":"AWS","Verified":true,"Raw":"AKIA..."} Where it sits in Tandera
trufflehog runs in the analyze phase of recon_web_lite and recon_web_full, against the JavaScript bundles and assets that katana and linkfinder recovered. The web-facing use is narrower than the git-history use most people know it for: it is looking for keys shipped to the browser.
Verified results map onto the secrets.yaml finding catalogue, which is what gives them a canonical severity and remediation rather than a raw detector name.
Using it in a pentest
Verified changes the severity, and the conversation. “We found a string matching an AWS key format” invites debate. “We found an AWS key that authenticates” ends it. Report the two categories separately and never blend them.
Do not use the credential beyond verification. Confirming a key is valid is in scope. Enumerating the account it opens is a different authorisation, and often a different contract. Verify, capture evidence, stop, escalate to the client.
Git history is where they live. A key deleted from HEAD is still in the commit that added it. Scanning a working tree instead of the repository history is the most common way this tool is used wrong.
Rotate is the remediation, not delete. A key removed from the repo but never rotated is still a valid key. Say so explicitly in the finding.