Secrets Exposure
Hardcoded credentials, API keys, tokens, and other secrets in web applications represent one of the most common and impactful vulnerabilities. Secrets can be found in JavaScript source, HTML comments, exposed configuration files, git repositories, and API responses.
Danger
Client-Side Secret Discovery
# Search JavaScript files for secrets:
curl -s https://target.com/js/app.js | grep -iE \
'api[_-]?key|apikey|secret|token|password|passwd|auth|credential|private[_-]?key'
# Search all JS files:
curl -s https://target.com/sitemap.xml | grep -oP 'https?://[^<]+\.js' | while read url; do
echo "--- $url ---"
curl -s "$url" | grep -inE 'api[_-]?key|secret|token|password|aws|firebase'
done
# Check HTML source for comments with secrets:
curl -s https://target.com | grep -iE '<!--.*(?:password|secret|key|token|TODO|FIXME|HACK)'
# Check for hardcoded Firebase config:
curl -s https://target.com | grep -oE 'AIza[0-9A-Za-z_-]{35}'
# Check JavaScript source maps (contain original source):
curl -s https://target.com/js/app.js | tail -1
# sourceMappingURL=app.js.map
curl -s https://target.com/js/app.js.map | jq '.sources'
# Source maps reveal the original unminified code!
# LinkFinder - extract hidden URLs and parameters from JS:
python3 linkfinder.py -i https://target.com/js/app.js -o cli# Search JavaScript files for secrets:
curl -s https://target.com/js/app.js | grep -iE \
'api[_-]?key|apikey|secret|token|password|passwd|auth|credential|private[_-]?key'
# Search all JS files:
curl -s https://target.com/sitemap.xml | grep -oP 'https?://[^<]+\.js' | while read url; do
echo "--- $url ---"
curl -s "$url" | grep -inE 'api[_-]?key|secret|token|password|aws|firebase'
done
# Check HTML source for comments with secrets:
curl -s https://target.com | grep -iE '<!--.*(?:password|secret|key|token|TODO|FIXME|HACK)'
# Check for hardcoded Firebase config:
curl -s https://target.com | grep -oE 'AIza[0-9A-Za-z_-]{35}'
# Check JavaScript source maps (contain original source):
curl -s https://target.com/js/app.js | tail -1
# sourceMappingURL=app.js.map
curl -s https://target.com/js/app.js.map | jq '.sources'
# Source maps reveal the original unminified code!
# LinkFinder - extract hidden URLs and parameters from JS:
python3 linkfinder.py -i https://target.com/js/app.js -o cliServer-Side Secret Discovery
# Environment files:
curl -s https://target.com/.env
curl -s https://target.com/.env.local
curl -s https://target.com/.env.production
curl -s https://target.com/.env.backup
# Configuration files:
curl -s https://target.com/config.json
curl -s https://target.com/config.yml
curl -s https://target.com/config.php
curl -s https://target.com/wp-config.php.bak
curl -s https://target.com/appsettings.json # ASP.NET
curl -s https://target.com/application.properties # Spring Boot
curl -s https://target.com/database.yml # Rails
# Docker/K8s secrets:
curl -s https://target.com/docker-compose.yml
curl -s https://target.com/Dockerfile
curl -s https://target.com/.dockerenv
# Debug/admin panels:
curl -s https://target.com/phpinfo.php
curl -s https://target.com/actuator/env # Spring Boot env vars
curl -s https://target.com/actuator/configprops # Spring config properties# Environment files:
curl -s https://target.com/.env
curl -s https://target.com/.env.local
curl -s https://target.com/.env.production
curl -s https://target.com/.env.backup
# Configuration files:
curl -s https://target.com/config.json
curl -s https://target.com/config.yml
curl -s https://target.com/config.php
curl -s https://target.com/wp-config.php.bak
curl -s https://target.com/appsettings.json # ASP.NET
curl -s https://target.com/application.properties # Spring Boot
curl -s https://target.com/database.yml # Rails
# Docker/K8s secrets:
curl -s https://target.com/docker-compose.yml
curl -s https://target.com/Dockerfile
curl -s https://target.com/.dockerenv
# Debug/admin panels:
curl -s https://target.com/phpinfo.php
curl -s https://target.com/actuator/env # Spring Boot env vars
curl -s https://target.com/actuator/configprops # Spring config propertiesGit Repository Mining
# Check for exposed .git:
curl -s https://target.com/.git/HEAD
# If output: ref: refs/heads/main → Git is exposed!
# Download the entire repository:
pip install git-dumper
git-dumper https://target.com/.git/ ./repo
# Search repository for secrets:
cd repo
# Search current code:
grep -rn 'password\|secret\|api_key\|token\|AWS_' --include='*.py' --include='*.js' --include='*.php'
# Search ALL commit history (including deleted secrets!):
git log --all -p | grep -iE 'password|secret|api_key|token' | head -50
# Use truffleHog for automated secret scanning:
trufflehog git file://./repo --only-verified
# Use gitleaks:
gitleaks detect -s ./repo -v
# Check specific sensitive files in history:
git log --all --full-history -- .env config.json secrets.yml
git show <commit_hash>:.env # View deleted .env file# Check for exposed .git:
curl -s https://target.com/.git/HEAD
# If output: ref: refs/heads/main → Git is exposed!
# Download the entire repository:
pip install git-dumper
git-dumper https://target.com/.git/ ./repo
# Search repository for secrets:
cd repo
# Search current code:
grep -rn 'password\|secret\|api_key\|token\|AWS_' --include='*.py' --include='*.js' --include='*.php'
# Search ALL commit history (including deleted secrets!):
git log --all -p | grep -iE 'password|secret|api_key|token' | head -50
# Use truffleHog for automated secret scanning:
trufflehog git file://./repo --only-verified
# Use gitleaks:
gitleaks detect -s ./repo -v
# Check specific sensitive files in history:
git log --all --full-history -- .env config.json secrets.yml
git show <commit_hash>:.env # View deleted .env fileCommon Secret Patterns (Regex)
AWS Access Key: AKIA[0-9A-Z]{16}
AWS Secret Key: [0-9a-zA-Z/+]{40}
GitHub Token: gh[ps]_[A-Za-z0-9_]{36,}
Slack Token: xox[baprs]-[0-9a-zA-Z-]{10,}
Google API Key: AIza[0-9A-Za-z_-]{35}
Stripe Key: sk_live_[0-9a-zA-Z]{24,}
JWT Token: eyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*
Private Key: -----BEGIN (RSA|EC|OPENSSH) PRIVATE KEY-----
Generic Password: (?i)(password|passwd|pwd)\s*[=:]\s*['"'][^'"']{4,}
Testing Checklist
- 1. Search all JavaScript files for API keys, tokens, and credentials
- 2. Check for source maps and download original source code
- 3. Check HTML comments for credentials and internal URLs
- 4. Probe for .env, config files, and backup files
- 5. Check for exposed .git repository and mine commit history
- 6. Check API responses for excessive data (tokens, internal IDs)
- 7. Run truffleHog or gitleaks on any exposed source code
- 8. Verify found secrets are active (but minimize scope — only confirm, don't exploit)
Evidence Collection
Secret Location: URL, file, or endpoint where the secret was found
Secret Type: API key, database password, private key, etc.
Verification: Proof the secret is active (redact the actual secret in your report)
CVSS Range: Read-only API key: 5.3–6.5 | Admin credentials: 9.1–9.8 | Cloud keys: 9.1–10.0
Remediation
- Rotate immediately: Any exposed secret must be revoked and rotated, not just removed from code.
- Environment variables: Store secrets in environment variables or a secrets manager (Vault, AWS Secrets Manager).
- Pre-commit hooks: Use tools like git-secrets, detect-secrets, or gitleaks as pre-commit hooks.
- CI/CD scanning: Integrate secret scanning in the build pipeline (GitHub Secret Scanning, GitLab Secret Detection).
- Block .env/.git: Configure web server to deny access to sensitive files and directories.
False Positive Identification
- Example/placeholder keys: Strings like AKIAIOSFODNN7EXAMPLE or test-api-key-1234 are documentation examples, not real secrets — verify the key is valid by testing it (with authorization).
- Revoked credentials: Exposed secrets in old git commits may already be rotated — note the exposure but verify current validity before rating severity.
- Public API keys: Some API keys are designed to be public (e.g., Google Maps browser keys with domain restrictions) — check if the key has usage restrictions configured.