What is a hardcoded secret?
On this page
A hardcoded secret is a credential, such as a password, API key, token or private key, written directly into source code, a configuration file in the repository or a build file, so that everyone who can read the code or the built artifact can read the credential too.
MITRE catalogs it as weakness CWE-798, "Use of Hard-coded Credentials": "The product contains hard-coded credentials, such as a password or cryptographic key" (CWE-798).
Two kinds
CWE-798 separates two cases, and they fail differently:
- Outbound. The code holds a credential it uses to reach something else:
stripe.Client("sk_live_..."), a database URL with a password in a settings file. Anyone with the repository can use that service as you. - Inbound. The code checks incoming logins against a built-in credential, such as a default admin password. Every installation shares it, and administrators often can't change it without a patch.
For application teams the outbound kind is the everyday problem, so the rest of this page is about that.
Why it is worse than it looks
A hardcoded value spreads with the code. It is in every clone, every fork, every CI checkout, every container image built from the repository and every backup of those. Deleting the line in a new commit leaves it in history. And because it is in code, it changes only with a deploy, so teams postpone replacing it, which keeps it valid for years.
It also defeats separation between environments. If the production key is in the code, the code can't run safely anywhere else, so it tends to run everywhere with the production key.
Common mistakes
- "It's a private repository." Access to a repository is usually broad: every developer, every CI integration, every tool with read access. Private narrows the audience; it doesn't make the value a secret again.
- Moving it to a committed config file.
config/production.ymlin Git is still hardcoding. CWE-798's advice is to "store passwords, keys, and other credentials outside of the code." - Build-time arguments. Values baked into an image through
ARGorENVend up in the image. OWASP says secrets "should never be hardcoded using docker ENV or docker ARG commands" (OWASP). - Removing the line but not the value. If the secret was ever committed, treat it as a leaked secret and reissue it.
The fix
Read the value from the process environment and supply it when the program starts. The code then names the variable, not the value:
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);This is the twelve-factor config approach, and it makes the same code safe to run with test keys locally and live keys in production.
How Crunu helps
Crunu supplies the values at run time. crunu run decrypts an environment in memory and starts your program with its variables, so neither the code nor a file in the project holds the value:
crunu run --env payments-api/production -- node server.jsThe production key lives in payments-api / production, readable only by people and machines granted that environment. Crunu does not find hardcoded secrets that are already in your code: it has no scanner. Use a secret scanner for that, then move each value it finds into an environment and reissue it. More on getting values to programs without files: runtime secret injection, and for the team side, how to share .env files with your team.
Sources
- CWE-798: Use of Hard-coded Credentials, checked October 30, 2026.
- OWASP Secrets Management Cheat Sheet, checked October 30, 2026.
From the blog
Secrets
A .env file leaked into Git: cleanup in the right order
Accidentally committed a .env file? Reissue the values first, then rewrite history, then stop it happening again. What scanners catch and what to record.
Sharing .env files guide
Secrets
Leaked Django SECRET_KEY: what it exposes and how to rotate
What someone can sign with your Django SECRET_KEY, why the fallback list works against you after a leak, and a rotation order that closes the gap.
Sharing .env files guide
AI agents
Do AI coding agents read your .env files?
What Claude Code, Cursor and Copilot do with .env files by default, why ignore rules don't stop an agent's shell, and how to test it with a fake key.
AI coding agents guide