Environment File Leaks Explained: Detecting and Rotating Secrets for NZ Sites
Detecting and responding to leaked environment files on NZ sites: what counts as a secret, rotation playbook, scanner caveats and a secrets manager overview.
Quick answer
If your site's .env file has been served to the public internet — even once — every secret in it must be treated as compromised and rotated immediately. A leaked environment file gives an attacker your database URLs, cloud API keys, payment processor tokens, and any other credential the application reads at runtime. There is no reliable way to tell from server logs whether the file was downloaded by a scanner or by a human, so the safe response is universal rotation.
The defensive baseline is: (1) make sure the file returns 404 instead of 200 from the public internet (see Web Server Hardening for NZ Sites), (2) move secrets out of .env files into a secrets manager for production, and (3) keep development secrets out of source control.
What "environment file leaks" actually means
An environment file is a text file that the application reads at startup to load configuration — database URLs, API keys, cloud credentials, OAuth client secrets, signing keys. The convention in modern frameworks (Laravel, Django, Node.js, Rails, Next.js) is .env at the project root, parsed by libraries like dotenv or built into the framework itself.
The leak happens when the file is reachable from the public internet. Three common causes:
- A
.envfile copied into the document root of the web server, so any request to/.envreturns the file contents - A
.envfile accidentally included in a deploy artefact — for example, a misconfigured CI pipeline that bundles the working directory into the Docker image published to a public registry - A backup archive (
.zip,.tar.gz,.sql) stored in the document root containing the full application source, including the.envfile
A scanner that reports secrets findings has detected one of: high-entropy strings that match known secret formats (AWS access keys, Stripe live keys, JWT signing keys, database URLs with embedded passwords), a .env-style file directly, or a backup archive containing secrets.
.env is not a theoretical risk. Automated bots crawl the public web specifically looking for these files. If your /.env returned 200 for any period of time, assume it has been harvested.
Why this matters for New Zealand sites under the Privacy Act 2020
An exposed environment file is almost always a notifiable event under the Privacy Act 2020 (1). Three points that matter operationally:
- Personal information often lives behind these credentials. A leaked database URL with an embedded password may give access to student records, parent contact details, staff HR data, or donor information — all of which are personal information under the Act (1).
- The "reasonable steps" test gets harder. A school or small business that has not implemented basic hardening (the
.envreturning 404, secrets not in source control) will struggle to argue it took the reasonable steps the Privacy Act expects (2). - Notification obligations are real. Once an unauthorised disclosure of personal information has occurred, the Privacy Act may require notification to affected individuals and to the Office of the Privacy Commissioner. Discovering the leak early and acting decisively makes the legal pathway much cleaner (1).
For the broader organisational context (who is responsible, who to call, when to escalate), see Cyber Security for NZ Educators and Small Business Cybersecurity Guide: Protect Your NZ Company in 2026.
What counts as a secret
Not every string in a .env file is equally dangerous. The scanner categories worth treating as urgent:
| Secret | Why urgent | Typical rotation path |
|---|---|---|
| Database URLs (DATABASE_URL, POSTGRES_PASSWORD, MYSQL_ROOT_PASSWORD) | Direct access to all stored data | Rotate password via DB console, redeploy with new env var |
| Cloud provider keys (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, GCP_SERVICE_ACCOUNT_KEY) | Full access to cloud account | Disable old key in IAM console, issue new key |
| OAuth client secrets (GOOGLE_CLIENT_SECRET, FACEBOOK_APP_SECRET) | Token impersonation, account takeover | Regenerate via provider developer console |
| Payment processor keys (STRIPE_SECRET_KEY, PAYPAL_CLIENT_SECRET) | Live payment fraud | Roll via Stripe/PayPal dashboard immediately |
| JWT signing secrets (JWT_SECRET, SESSION_SECRET) | Session forgery | Regenerate, force session reset for all users |
| Email provider keys (SENDGRID_API_KEY, MAILGUN_API_KEY) | Email spoofing from your domain | Revoke via provider dashboard |
| Internal service tokens (GITHUB_TOKEN, SLACK_WEBHOOK_URL) | Lateral movement | Revoke, regenerate |
SESSION_SECRET is special: rotating it invalidates every active session on the site. Do this late at night, expect a wave of password resets, and warn users.
The rotation playbook — first 60 minutes
If you have confirmed (or strongly suspect) your .env file was exposed, follow this sequence. Speed matters — every minute of delay is a minute an attacker can use the credentials.
0–10 minutes — contain the leak.
- Confirm the file is currently returning
404, not200. If it still returns200, block it immediately (see Web Server Hardening for NZ Sites for nginx and Apache snippets). - Take the file out of the document root. Move it one directory above (
mv .env ../) or rename it (mv .env .env.disabled.bak).
10–30 minutes — rotate the highest-impact secrets.
- Rotate any cloud provider keys first (AWS, GCP, Azure). These typically have the broadest blast radius. Disable the old key, generate a new key, redeploy with the new value.
- Rotate the database password next. Most managed databases (RDS, Cloud SQL, Postgres on managed hosting) let you change the master password in the console without downtime if connection pooling is in place.
30–60 minutes — rotate application-layer secrets.
- Rotate payment processor keys via the Stripe / PayPal / Windcave dashboard. These are live keys, so this is urgent if your site processes real payments.
- Rotate the JWT or session secret last, because rotating it forces every active user to re-authenticate. Do this in a low-traffic window and warn users via a banner.
After 60 minutes — verify and document.
- Search your access logs for requests to
/.env,/.env.local,/.env.production,/backup.zip. Note the IP addresses and timestamps. - If the leaked secrets included any path to personal information, treat this as a notifiable event under the Privacy Act 2020. Contact your privacy officer or legal counsel, and review the Office of the Privacy Commissioner's breach notification guidance (1).
- Write up an incident timeline — what was leaked, when, who was notified, what was rotated. This document is what the Privacy Commissioner will ask for if the breach escalates.
The free NZAI Security Check re-scans your site and confirms the /.env path is now returning 404.
Scanner caveats — what automated tools catch and miss
The scanner secrets finding is useful but imperfect. Three categories worth knowing:
1. High-entropy string detection. Scanners flag strings that look random and match known formats — AKIA... for AWS keys, sk_live_... for Stripe live keys, JWT-shaped strings. This catches obvious leaks but produces false positives on test fixtures, public API keys that are meant to be public (for example, a Stripe publishable key starts with pk_live_ and looks secret but is designed to be embedded in client-side code).
3. Regex pattern matching. Scanners match secrets against regex patterns — password=, api_key=, bearer eyJ.... This catches straightforward leaks but misses secrets that are base64-encoded, JSON-stringified, or stored in non-obvious file types.
2. Known-secret database lookup. Some scanners hash the suspected secret and check it against a database of known-leaked secrets (GitHub's token-leak database, have-i-been-pwned-style lists for cloud keys). This is the most reliable check but requires the scanner to phone home.
A scanner that says secrets is worth fixing even if it is a false positive — the false positive rate is low enough that the rotation cost is justified, and the cost of a missed real secret is high. If you are unsure, treat every flagged secret as real and rotate.
For the broader NZ-context baseline (devices, accounts, phishing), see Building Cyber-Safe Habits as an NZ Educator.
Move to a secrets manager — production-only
For production systems handling real data, the long-term fix is to stop using .env files entirely. A secrets manager is a dedicated service that stores, audits, and rotates secrets at runtime. The application fetches the secret over an authenticated API call at startup, and never writes it to disk.
The most common options for NZ sites:
- HashiCorp Vault — open source, self-hosted, complex to operate but the most flexible. Used by large NZ government and education providers.
- AWS Secrets Manager / AWS Systems Manager Parameter Store — managed, integrates with IAM. Used by NZ sites already on AWS.
- Google Cloud Secret Manager — managed, integrates with GCP IAM. Used by NZ sites on Google Cloud.
- Azure Key Vault — managed, integrates with Azure AD. Used by NZ sites on Microsoft Azure.
- 1Password Secrets Automation — newer entrant, well-suited to small teams that already use 1Password for human credentials (3).
For a small NZ school site, AWS Secrets Manager or 1Password Secrets Automation is usually the right starting point — managed, low operational overhead, and integrates with most CI/CD platforms.
The migration path is straightforward: provision the secret in the manager, remove it from the file, point the application at the manager's API, and redeploy. Keep .env files for local development only.

Common mistakes to avoid
From running the free scanner across New Zealand school and small-business sites, the most frequent missteps are:
- Rotating only the database password, not the cloud keys. Cloud keys typically have a wider blast radius than the database. Rotate both.
- Forgetting the OAuth refresh tokens. If a Google or Microsoft OAuth refresh token leaked, the attacker has long-lived access until that token is revoked. Revoke via the provider's developer console.
- Re-using the same secret across staging and production. If staging's
.envis leaked, production is also compromised. Use distinct secrets per environment. - Treating "scanner said it was a false positive" as evidence of safety. False positive rates are low. Rotate anyway.
- Storing
.envfiles in a public GitHub repository by accident. If this happened, treat it as a full secret leak — GitHub's token scanner will have flagged it within minutes, but the secret has been harvested by GitHub's full-text search already.
For the response-header piece that prevents the file from being served in the first place (CSP, HSTS, X-Frame-Options), see Security Headers Explained for NZ Sites.
Knowledge check
Test your understanding of environment file leaks with these questions. Click or tap each card to flip it and see the answer.
secrets finding on /.env, but curl -sI https://yoursite.nz/.env returns HTTP/2 404. The file is not currently exposed. Do you still need to rotate the secrets inside it?tap to flip/.env from weeks or months ago. Bots that harvest .env files do not announce themselves; they quietly download the file once and add it to a corpus. If the file was ever served (and the scan finding suggests the scanner found something that led to the report), rotate every secret inside it. The cost of rotation is low compared to the cost of a credential being live in a bot's database (1).secrets findings on every page load. Have you missed something?tap to flip.env file is still in the deploy artefact or the source repository. Migrating production secrets to AWS Secrets Manager fixes the production runtime, but if the application code still expects to find a .env file at startup (because the development environment uses one), the deploy artefact will include an empty .env template, and the scanner may be matching residual secret patterns or detecting the .env filename itself. The fix is to confirm the application no longer reads .env in production (only in dev), and to add a .env entry to .gitignore and your deploy-exclude list (3).Sources and references
[1] New Zealand. Office of the Privacy Commissioner. (2025). Privacy Act 2020 — breach notification guidance. https://www.privacy.org.nz/responsibilities/notify/
[2] CERT NZ. (2025). Critical controls for small organisations. https://www.cert.govt.nz/
[3] 1Password. (2025). 1Password Secrets Automation documentation. https://developer.1password.com/docs/secrets-automation/
[4] HashiCorp. (2025). Vault — secrets management documentation. https://developer.hashicorp.com/vault/docs
[5] Mozilla. (2025). OWASP Top 10 — A02:2021 Cryptographic Failures. https://owasp.org/Top10/A02_2021-Cryptographic_Failures/
[6] GitHub. (2025). Secret scanning alerts documentation. https://docs.github.com/en/code-security/secret-scanning
[7] Mozilla. (2025). MDN Web Docs — Environment variables on the web. https://developer.mozilla.org/en-US/docs/Web/API/Window/environment
What to do next
- Confirm your site's
/.envpath returns 404 from the public internet. The Web Server Hardening for NZ Sites guide has copy-paste nginx and Apache deny rules. - Run the Free Website Security Check to confirm the
secretsfinding has cleared after rotation. - For the connection-side piece that protects data in transit (TLS), see the TLS 1.2 and 1.3 Explained for NZ Sites guide.
- For the certificate-lifecycle piece that pairs with TLS (renewal windows, monitoring), see SSL Certificate Management for NZ Sites.
- For the response-header piece (CSP, HSTS, X-Frame-Options), see Security Headers Explained for NZ Sites.
- For everything else the scanner checks (TLS, cookies, mixed content, redirects), the free scanner covers all of it in one pass.