# .env files are listed in .gitignore

- **Pattern:** `ab-000017` (`security-headers.basic-hygiene.env-in-gitignore`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-17
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000017
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000017)

## Why it matters

A `.env` file committed to git is a permanent credential leak — even after deletion, the file lives in git history and is readable to anyone with repository access, including all future contributors, CI/CD systems, and anyone who ever clones the repo. Stripe keys, database passwords, and OAuth secrets committed to a private repo are exposed the moment the repo is accidentally made public or an employee account is compromised. OWASP A02 (Cryptographic Failures) covers secret exposure; CWE-540 and CWE-538 specifically address sensitive information in committed files. AI code generators routinely create `.env.local` files and forget to update `.gitignore`, making this one of the highest-frequency findings across AI-built projects.

## Severity rationale

High because secrets committed to git history are irrecoverable without rotation — a single accidental public repo exposure or account compromise exposes all credentials permanently.

## Remediation

Add `.env` patterns to `.gitignore` before committing any environment files. If `.env` files are already tracked, remove them from git's index immediately.

```
# .gitignore — add all of these
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
.env*.local
```

If secrets were already committed: `git rm --cached .env.local`, then commit the removal, then **rotate every secret in that file immediately** — treat them as compromised. Only `.env.example` with placeholder values should ever be committed.

## Detection

- **ID:** `env-in-gitignore`
- **Severity:** `high`
- **What to look for:** Check `.gitignore` for `.env` patterns. Count all `.env*` files present in the project root (`.env`, `.env.local`, `.env.production`, `.env.development`, `.env.*.local`, etc.). For each, verify it is covered by a `.gitignore` pattern. Also check if any `.env` files (other than `.env.example` or `.env.template`) are tracked in git.
- **Pass criteria:** `.gitignore` contains at least 1 pattern that excludes `.env` files (e.g., `.env`, `.env.local`, `.env*.local`). No more than 0 actual `.env` files with secrets are tracked in git. Report: "X `.env*` files found, all covered by .gitignore patterns."
- **Fail criteria:** `.gitignore` does not contain `.env` patterns, or `.env` files (other than `.env.example`) appear to be tracked in git.
- **Skip (N/A) when:** Never — even projects without env vars should have the gitignore pattern as a safety measure.
- **Detail on fail:** `".gitignore does not contain any .env patterns — environment files may be committed to git"` or `".env.local appears to be tracked in git despite gitignore rules"`
- **Remediation:** Environment files often contain API keys, database credentials, and other secrets. They must never be committed to git:

  ```
  # .gitignore — add these lines
  .env
  .env.local
  .env.development.local
  .env.test.local
  .env.production.local
  .env*.local
  ```

  If `.env` files are already committed, remove them from tracking: `git rm --cached .env.local` and rotate any exposed secrets immediately.

## External references

- cwe CWE-540
- cwe CWE-538
- owasp A02

Taxons: cryptography-and-secrets

HTML version: https://auditbuffet.com/patterns/ab-000017
