Charles Timmons / Tools

Tool · 4 min read

Blue team

leakcheck

Find leaked secrets and PII in a repo — including the ones hiding in its history.

Source & docs: github.com/witlesswitness/sec-toolkit/leakcheck. MIT-licensed; free to use and fork.

In brief. leakcheck scans a local git repo for leaked secrets and PII — not just the current files, but the full commit history and commit messages, where an accidentally-committed key usually survives long after it's “deleted.” It knows the formats of common credentials (AWS, GitHub, Stripe, Slack, Google, private keys, JWTs), finds emails and IPs, shows every secret redacted, ranks by severity, and exits non-zero on a high-risk find so it fits CI.

Why I built it

Right after I shipped this site I found my own email address sitting in years of git history, and cleaning it meant rewriting every commit — deleting a value in a new commit does nothing, because the old one still lives in history. That is the whole problem with committed secrets: the dangerous copy is almost never the one in the current files. I wanted a tool that looks where the leak actually hides.

How it works

You point it at a local repo and it scans three places: the working tree (current files), the full history (every line ever added, via git log -p, so a secret removed in a later commit is still caught), and commit messages and author metadata (where emails, IPs, and the occasional pasted token end up).

Detection is high-precision by default: regexes for the formats real credentials take — private key blocks, AWS access keys, GitHub classic and fine-grained tokens, Stripe live keys, Slack, Google, SendGrid, Twilio, npm, JWTs — plus a conservative key = "value" pattern, and emails and IP addresses for PII. Two noisier modes are opt-in: --entropy catches unknown key shapes by randomness, and --aggressive-pii adds phone/SSN-style patterns.

Every secret is printed redacted — ghp_…aaaa, AKIA…MPLE — never in full, so the report itself isn't a new leak.

Using it

# build a throwaway repo with planted fake secrets and scan it
python -m leakcheck --demo

# scan a repo you control
python -m leakcheck /path/to/repo
python -m leakcheck /path/to/repo --no-history        # working tree only, fast
python -m leakcheck /path/to/repo --format json -o findings.json

It exits 1 when a critical or high-severity secret is found, so a CI job fails the build if someone commits a key.

Scope — and a deliberate limit

leakcheck is for scanning repos you own or are authorized to assess: your own exposure, or a client's with permission. I built it that way on purpose. A tool that trawled arbitrary public repositories to collect other people's keys and personal data would be a harvesting tool, not a defensive one, so it isn't that. If you ever find a real secret in a repo you don't own, the right move is to tell the owner or GitHub — not to use it.

If it finds something real

Assume a committed secret is compromised and rotate it first. Then remove it from history, not just the latest commit, and force-push — the same rewrite I had to do for my own leak. leakcheck tells you what's exposed and where; rotating and rewriting is the follow-up only you can do.

Questions or feedback? Send me a note →