Secrets managed via environment variables or secrets manager; no credentials committed to version control
Why it matters
Hardcoded credentials in source code (CWE-798) or committed .env files (CWE-312) expose API keys, database passwords, and service tokens to every person with repository access — and to public GitHub if the repo is ever made public or forked. OWASP A07 (Identification and Authentication Failures) and NIST IA-5 both classify hardcoded credentials as a critical authentication control failure. PCI DSS v4.0 Req-8.6.2 explicitly prohibits hardcoded passwords/passphrases in scripts, configuration/property files, and bespoke source code. Unlike most vulnerabilities, secrets in git history persist even after the secret is removed from the current codebase — they require key rotation, not just file deletion.
Severity rationale
Info in this bundle context because other patterns cover active secret exposure; this pattern focuses on the secrets management hygiene baseline rather than a detected active leak.
Remediation
Store all secrets in environment variables and exclude .env files from version control. Create .env.example as a committed template with placeholder values.
# .env.example — commit this; never commit .env
DATABASE_URL=postgres://user:pass@localhost:5432/mydb
STRIPE_SECRET_KEY=sk_test_REPLACE_ME
SENTRY_DSN=https://REPLACE_ME@sentry.io/123
Add to .gitignore:
.env
.env.local
.env.*.local
If secrets were ever committed, rotate them immediately — do not rely on git rm alone, as the values remain in history. Use git filter-repo to scrub history, then force-push. For production secret management: Vercel Dashboard → Settings → Environment Variables; AWS Systems Manager Parameter Store; or HashiCorp Vault for self-hosted.
Detection
-
ID:
secrets-management -
Severity:
info -
What to look for: Enumerate every relevant item. Check for
.env.exampleor similar template file (without actual values). Look for secrets management in code: environment variable usage, AWS Secrets Manager integration, HashiCorp Vault, or similar. Verify.gitignoreexcludes.env,.env.local, or similar files. Check git history for any committed secrets. -
Pass criteria: At least 1 of the following conditions is met. Secrets are stored in environment variables or a secrets manager. No credentials are committed to version control. A
.env.exampleexists as a template. -
Fail criteria: Secrets are hardcoded in source code or config files, or committed to git history. No
.env.exampletemplate. -
Skip (N/A) when: The project has no secrets or external service dependencies.
-
Detail on fail:
"API keys hardcoded in config files. No .env.example template found."or"AWS credentials committed to git history (possibly already rotated)." -
Remediation: Use environment variables. Create
.env.example:# .env.example (commit this to git) DATABASE_URL=postgres://user:pass@localhost:5432/db API_KEY=your_api_key_here SENTRY_DSN=https://xxx@sentry.io/123Then add to
.gitignore:.env .env.local .env.*.localIn your app, use
process.env:const apiKey = process.env.API_KEY; // Never commit the real valueUse your platform's secrets manager for deployment:
- Vercel: Dashboard → Settings → Environment Variables
- AWS: Systems Manager → Parameter Store or Secrets Manager
- Railway/Render: Add env vars in UI before deploying
External references
- cwe · CWE-798 — Use of Hard-coded Credentials
- cwe · CWE-312 — Cleartext Storage of Sensitive Information
- owasp:2021 · A07 — Identification and Authentication Failures
- nist:rev5 · IA-5 — Authenticator Management — secrets rotation and protection
- pci-dss:4.0 · Req-8.6.2 — Passwords/passphrases for application and system accounts are not hardcoded in scripts, config, or source code
Taxons
History
- 2026-04-18·v1.0.0·Initial import from deployment-readiness·automated