Secrets Detection Checks
Hardcoded secrets in source code are a critical security risk. Once committed to version control, secrets can be exposed to anyone with repository access and are difficult to fully remove.
secrets-api-key
Severity: Critical
What It Detects
Hardcoded API keys from popular services:
- AWS Access Keys (
AKIA...) - OpenAI API Keys (
sk-...) - Anthropic API Keys (
sk-ant-...) - GitHub Personal Access Tokens (
ghp_...) - Stripe API Keys (
sk_live_...) - Slack Tokens (
xox...) - Generic API key patterns
Why It's Dangerous
Exposed API keys allow attackers to:
- Access your cloud services as you
- Incur charges on your accounts
- Access sensitive data through APIs
- Use your services for malicious purposes
- Pivot to other systems using found credentials
Example Vulnerable Code
// Hardcoded AWS credentials
const aws = new AWS.S3({
accessKeyId: 'AKIAIOSFODNN7EXAMPLE', // DANGEROUS!
secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
});
// Hardcoded API key
const openai = new OpenAI({
apiKey: 'sk-abc123def456...' // DANGEROUS!
});
// API key in string
const API_KEY = "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";Safe Alternative
// Use environment variables
const aws = new AWS.S3({
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
});
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});Create a .env file (never commit this):
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
OPENAI_API_KEY=sk-abc123def456...Add to .gitignore:
.env
.env.local
.env.*.localsecrets-password
Severity: Critical
What It Detects
Hardcoded passwords in code:
- Password assignments in strings
- Database connection strings with embedded passwords
- Basic auth credentials
Why It's Dangerous
Hardcoded passwords:
- Are visible to anyone reading the code
- Cannot be easily rotated
- Often reused across services
- End up in version control history forever
Example Vulnerable Code
// Direct password assignment
const password = "super_secret_password123"; // DANGEROUS!
// Database connection with password
const connectionString =
"postgresql://user:mypassword@localhost/db"; // DANGEROUS!
// Basic auth
const auth = {
username: 'admin',
password: 'admin123' // DANGEROUS!
};
// Configuration object
const config = {
db: {
password: 'db_password_here' // DANGEROUS!
}
};Safe Alternative
// Use environment variables
const password = process.env.DB_PASSWORD;
const connectionString =
`postgresql://${process.env.DB_USER}:${process.env.DB_PASSWORD}@localhost/db`;
// Or use a connection object
const dbConfig = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
};For production, consider:
- Secrets managers (AWS Secrets Manager, HashiCorp Vault)
- Kubernetes secrets
- Cloud provider secret stores
secrets-private-key
Severity: Critical
What It Detects
Private keys embedded in source code:
- RSA private keys (
-----BEGIN RSA PRIVATE KEY-----) - EC private keys (
-----BEGIN EC PRIVATE KEY-----) - OpenSSH private keys (
-----BEGIN OPENSSH PRIVATE KEY-----) - PGP private key blocks
Why It's Dangerous
Private keys are the foundation of cryptographic security:
- Compromised TLS keys allow man-in-the-middle attacks
- Compromised signing keys allow forged signatures
- Compromised SSH keys allow unauthorized server access
- Keys cannot be "unexposed" once in version control
Example Vulnerable Code
const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA0Z3US...
-----END RSA PRIVATE KEY-----`; // DANGEROUS!
const sshKey = `-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEA...
-----END OPENSSH PRIVATE KEY-----`; // DANGEROUS!Safe Alternative
// Load from file (file should be .gitignored)
import fs from 'fs';
const privateKey = fs.readFileSync('./keys/private.pem', 'utf8');
// Load from environment variable
const privateKey = process.env.PRIVATE_KEY;
// Note: Newlines in env vars may need to be \n escaped
// For production, use a secrets manager
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
const client = new SecretsManager();
const secret = await client.getSecretValue({ SecretId: 'my-private-key' });Store keys properly:
# .gitignore
*.pem
*.key
keys/Best Practices for Secrets Management
1. Never Commit Secrets
- Add secret files to
.gitignore - Use pre-commit hooks to scan for secrets
- Review diffs before committing
2. Use Environment Variables
// ✅ Good
const apiKey = process.env.API_KEY;
// ❌ Bad
const apiKey = "sk-abc123...";3. Use Secrets Managers
For production environments:
- AWS Secrets Manager
- HashiCorp Vault
- Google Cloud Secret Manager
- Azure Key Vault
4. Rotate Compromised Secrets
If a secret is exposed:
- Immediately revoke the exposed credential
- Generate a new credential
- Update all services using it
- Audit access logs for misuse
5. Use .env.example
Provide a template without actual values:
# .env.example (safe to commit)
API_KEY=your_api_key_here
DB_PASSWORD=your_db_password_hereSummary
| Check | Severity | Key Fix | |-------|----------|---------| | secrets-api-key | Critical | Use environment variables | | secrets-password | Critical | Use env vars or secrets managers | | secrets-private-key | Critical | Load from files or secrets managers |
Next Steps
- Network Security - TLS configuration
- Supply Chain - Dependency security
- Reviewing Findings - How to fix issues