Documentation

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.*.local

secrets-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:

  1. Immediately revoke the exposed credential
  2. Generate a new credential
  3. Update all services using it
  4. 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_here

Summary

| 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