How to recover from exposed database credentials
Exposed DATABASE_URL or DB_PASSWORD is a P1: attackers may bypass your application logic and connect directly. Speed matters, but panicked password changes without draining connection pools can leave old sessions alive or break production if order is wrong.
1. Immediate containment (minutes)
- Identify scope: dev-only vs production; static IP allowlists vs public
*.rds.amazonaws.com. - Restrict network if your platform allows emergency security group / firewall rule tightening (careful not to lock yourself out without a bastion).
- Enable / check database audit logs (who connected, from where) — AWS RDS, Cloud SQL, etc.
2. Rotate credentials (safe sequence)
A. Create new database user or password
- Prefer new user with same grants, then swap app config — clearer rollback.
- For managed services, use the vendor’s rotate master password flow if appropriate (understand downtime).
B. Update all application instances
Rolling deploy:
- Stage new secret in secret manager / env injection.
- Redeploy workers and APIs so new pools pick up credentials.
- Monitor error rates (
authentication failedspikes mean missed consumers).
C. Revoke old password / drop old user
Only after traffic is healthy on the new credential.
PostgreSQL example (illustrative):
ALTER USER app_runtime WITH PASSWORD 'new-strong-random-password';
-- After all apps moved to new user, optionally:
-- DROP USER old_leaked_user;
3. Assume data access until logs prove otherwise
If credentials were public long enough:
- Review sensitive tables for unusual SELECT patterns if audit logging exists.
- Consider notification obligations under GDPR/CCPA/contract — involve legal.
4. Invalidate application sessions if JWT signing was co-located
If the same leak included JWT_SECRET, rotating DB password is not enough — attackers could forge tokens. Rotate signing keys and invalidate sessions per your auth library’s docs.
5. Cloud provider references
- AWS RDS: security groups, parameter groups, IAM DB auth — RDS security
- Google Cloud SQL: Authorize networks
- Azure Database: Firewall rules
6. Prevention (developer machines)
- No prod
DATABASE_URLon laptops unless break-glass. - Store dev URLs in PassStore or strict gitignored
.env— secure database credentials on macOS.