Where do hardcoded secrets usually hide in a repository?
In short
- In history, from before .gitignore existed — deleting the file later does not remove it.
- In the client bundle, when a public environment prefix ships the value to every visitor.
- In .env.example, test fixtures, seeds and CI workflow files, which are all committed by design.
The obvious one — a committed .env — is the one most projects have already defended
against, which is why it is rarely where the live credential is.
Check history first, because that is the only place where the security state has already
changed: git log --all --full-history -- .env, and git log -p --all -S 'SECRET' to
find when a string first appeared. If a key was ever pushed, it is compromised. Rotate it.
Rewriting history afterwards is cleanup, not remediation.
Then check what ships to the browser. Framework conventions decide this by prefix, so a variable can be leaked to every visitor by a one-word rename. Grep the built output rather than trusting the rule from memory.
After that, the files that are committed on purpose: .env.example with a real value
someone pasted in to debug, fixtures and seeds that needed a token which would parse, and
CI workflow YAML where a value was inlined to unblock a failing pipeline.
And then everything that is not the repository at all — the screenshot in the issue, the
stack trace with a connection string, the README curl written with a live token, the
boot log that prints the whole config object.
