A staging environment connected to the production database is not a staging environment — it is a second production environment with weaker access controls. Bugs discovered during staging testing can corrupt, delete, or expose real user data. Developers routinely write aggressive cleanup scripts, run schema migrations, and insert test data in staging, assuming isolation that doesn't exist. NIST SC-7 requires boundary protection between system components. OWASP A05 flags misconfiguration that allows unintended data access. A staging breach that exposes a shared database URL puts the production database password in the attacker's hands.
Medium because connecting staging to a production database or using production credentials in staging directly risks real user data during routine development and testing operations.
Provision a completely separate database for staging with its own credentials, host, and data. Never copy production data to staging — generate synthetic or anonymized test data instead.
# .env.staging
DATABASE_URL=postgresql://user:stagingpass@staging-db.internal/app_staging
# .env.production
DATABASE_URL=postgresql://user:prodpass@prod-db.internal/app_prod
For seeding, use a dedicated script that inserts synthetic records:
npm run db:seed:staging # inserts test users, orders, etc. — no real data
Verify isolation by confirming that the staging DATABASE_URL host does not appear in any production configuration file.
ID: environment-security.secrets-management.staging-isolation
Severity: medium
What to look for: Check configuration files and deployment setup. Verify that the staging environment uses a separate database URL from production. Look for documentation or scripts that indicate staging data is test/synthetic, not a clone of production.
Pass criteria: Count the number of distinct DATABASE_URL values across environment configs. Staging environment has its own database with test or synthetic data -- at least 2 unique database URLs must exist for staging and production. Production database credentials are not used in staging configuration.
Fail criteria: Staging database is a direct copy of production or uses production credentials.
Skip (N/A) when: The project does not have a staging environment.
Detail on fail: "Staging .env uses production DATABASE_URL" or "Staging environment appears to connect to production database based on config".
Remediation: Create a staging database separate from production:
# .env.staging
DATABASE_URL=postgresql://user:pass@staging-db.example.com/app_staging
# .env.production
DATABASE_URL=postgresql://user:pass@prod-db.example.com/app_prod
Fill staging with test data, not a production backup. This prevents accidental data leaks from staging and ensures staging tests don't corrupt production-like data.