📋 What Is It?
Insecure Application Secrets Storage occurs when the secrets a function needs-database credentials, API keys, signing keys, OAuth client secrets, encryption keys-are kept somewhere convenient for the developer but readable by an attacker: plaintext environment variables, hardcoded in committed source, baked into the deployment artifact, or written into infrastructure-as-code. It is not a single leaked password; it is the habit of treating secrets as ordinary configuration. Serverless makes it worse-many small functions copy secrets widely, everything is defined as code so a plaintext secret is one git push from permanent history, and third-party deps run in the same process and can read the environment. A valid credential needs no exploit-it is the access.
⚠️ Common Exploits
- Public/Private Repos: Bots scan code hosts and find committed keys within minutes of a push
- Git History: Deleting the line does not remove it-
git grepover all revisions recovers it - Deployment Artifact:
GetFunctionyields a download URL; a bundled.envcomes with it - Platform API:
lambda:GetFunctionConfigurationdumps plaintext env vars - Compromised Dependency: Reads
process.envand POSTs it to an attacker endpoint - Echoed to Logs:
console.log(process.env)persists in CloudWatch - Over-Shared & Static: One reused, never-rotated secret is a master key
🔴 Attack Flow
(repo, history, artifact, config, or logs)
↓
2. Read the secret - no exploit needed
(the value is in plaintext where it was left)
↓
3. Authenticate as the application
(DB credential / API key / signing key)
↓
4. Expand with over-shared, static creds
(reuse to pivot; keys valid for months)
↓
5. IMPACT: Full DB + payment-provider compromise!
❌ Vulnerable Code
✅ Secure Code
✓ Prevention Checklist
- Store secrets in Secrets Manager / SSM SecureString
- Encrypt at rest with KMS
- Fetch at runtime with a least-privilege role
- Cache in memory across warm invocations
- Reference secrets by name/ARN, never by value
- Keep secrets out of code, env vars, IaC, and Git
- Git-ignore & exclude
.envfrom the package - Rotate secrets automatically on a schedule
- Scope one secret per purpose; no shared master key
- Scan repos & artifacts (gitleaks / trufflehog)
- Redact secrets from logs and error output
- Prefer IAM roles / short-lived creds over static keys
🔍 Detection & Tools
Secret Stores:
Secret Scanning:
How to Test:
git grep "sk_live_" $(git rev-list --all)- scan full historyaws lambda get-function-configuration- check for plaintext env vars- Download the artifact;
unzip -land grep for.env/.pem/.key - Filter CloudWatch logs for known secret prefixes
- Confirm secrets are fetched at runtime, not embedded
- Verify rotation is enabled and roles are per-function scoped
🌍 Real-World
Described as incident classes-patterns repeatedly observed across the industry-because insecure secret storage is defined by how routinely and generically it happens:
- Leaked Keys in Public & Shared Repositories: Cloud keys and passwords hardcoded in source or IaC then pushed; automated scanners find them within minutes, and leaked cloud keys are widely observed launching expensive compute (crypto mining) before the owner notices.
- Environment-Variable Secret Exposure: A separate weakness (SSRF, vulnerable dep, over-broad read) exposes a function's plaintext environment, turning an info-disclosure bug into full credential disclosure.
- Compromised Dependency Reading the Environment: Malicious packages read
process.env/os.environand POST the contents outward-no vulnerability in your own code required.
📌 Quick Tips
- DO NOT put live secrets in plaintext env vars
- DO NOT hardcode or commit secrets to Git
- DO NOT log the event, config, or environment
- DO fetch from a managed store at runtime
- DO rotate (deleting the line is not enough)
- DO scope access per function, least-privilege
- DO scan repos & artifacts pre-commit and in CI
📜 Compliance
Related Standards:
- OWASP Top 10 - Cryptographic Failures
- PCI-DSS Requirement 3 & 8 - Protect & Authenticate
- NIST 800-53 IA-5 - Authenticator Management
- GDPR / HIPAA - Protecting Access Credentials
- SOC 2 CC6.1