Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Academy Secrets in Source Code
Beginner · 15 min

Secrets in Source Code

Understand why API keys committed to git are permanently compromised and how to prevent and remediate them.

1 Secrets Committed to Git History

When API keys, passwords, or tokens are committed to a git repository — even briefly and then deleted — they remain accessible in git history permanently. Automated scanners monitor public repositories in real time.

Common secret types found in repos:

  • Cloud provider keys (AWS Access Key ID, GCP service account JSON)
  • Payment API keys (Stripe, PayPal, Square)
  • Database connection strings with passwords
  • SSH private keys, TLS certificates
  • Internal API tokens and bearer tokens
  • OAuth client secrets

Why deletion does not help:

# Secret committed in commit abc123
git add config.js  # File contains AWS_SECRET_KEY = "AKIA..."
git commit -m "Add config"

# Secret "deleted" in next commit
git add config.js
git commit -m "Remove API key from source"

# Key is STILL accessible:
git show abc123:config.js  # Shows the original file with the key
git log --all -p | grep "AKIA"  # Finds it in history

Within minutes of pushing to GitHub, automated tools like GitGuardian and truffleHog find and catalog the exposed secret.

2 Prevention and Remediation

Use pre-commit hooks to prevent secrets from being committed, and if a secret is exposed, rotate it immediately then clean history.

Pre-commit hook with git-secrets:

pip install detect-secrets
detect-secrets scan > .secrets.baseline
detect-secrets audit .secrets.baseline

# Add to pre-commit hook (using pre-commit framework)
# .pre-commit-config.yaml:
- repo: https://github.com/Yelp/detect-secrets
  rev: v1.4.0
  hooks:
    - id: detect-secrets
      args: ['--baseline', '.secrets.baseline']

.gitignore patterns to prevent secret files:

.env
.env.local
.env.production
*.key
*.pem
*.p12
*credentials*
secrets/
config/secrets.yml

If secrets are already committed — remediation:

  1. Immediately revoke and rotate the exposed secret
  2. Assume it was already harvested
  3. Use BFG Repo Cleaner or git filter-repo to rewrite history
  4. Force-push the cleaned history (coordinate with team)
  5. Make GitHub repo private if it was public

Knowledge Check

0/3 correct
Q1

A developer pushes a commit with an API key to GitHub, then immediately deletes it in the next commit. Is the key still exposed?

Q2

What is the first action to take when discovering an API key was committed to a public repository?

Q3

What tool can prevent secrets from being committed in the first place?

Code Exercise

Move Hardcoded Secret to Environment Variable

The code has a Stripe API key hardcoded directly. Move it to an environment variable and add validation that it is set before use.

javascript