# All default credentials are removed from infrastructure components

- **Pattern:** `ab-001179` (`ecommerce-pci.cardholder-data.no-default-credentials`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001179
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001179)

## Why it matters

PCI-DSS 4.0 Req 2.1 requires that all default passwords and unnecessary default accounts are removed before system components enter production. Req 8.3 mandates strong authentication for all users. Hardcoded credentials — `postgres:postgres` in a Dockerfile, `sk_live_` keys in a `.env` committed to git — are the lowest-effort, highest-yield targets for attackers. CWE-798 (Use of Hard-coded Credentials) and CWE-1188 (Initialization with Default Value) are both directly exploitable. OWASP A05 (Security Misconfiguration) rates this category as endemic. A leaked Stripe live key means unauthorized charges or refunds; a leaked DB admin password means direct CDE access.

## Severity rationale

Critical because a hardcoded live credential found in a public or semi-public repository enables immediate unauthorized access to payment systems or the database with no additional exploitation needed.

## Remediation

Replace every hardcoded value with an environment variable reference and add those variable names to `.gitignore`-protected `.env.local`. Use a secrets manager (AWS Secrets Manager, Supabase Vault) in production — no secret should exist anywhere in the codebase, even in git history.

```dockerfile
# Before (fails Req 2.1)
ENV POSTGRES_PASSWORD=postgres

# After
ENV POSTGRES_PASSWORD=${DB_PASSWORD}
```

For Terraform, use `var.db_password` sourced from a tfvars file that is git-ignored, or use `aws_secretsmanager_secret_version` as the password source. Audit git history with `git log -S 'sk_live_'` to confirm secrets were never committed.

## Detection

- **ID:** `no-default-credentials`
- **Severity:** `critical`
- **What to look for:** Enumerate all infrastructure files that could contain credentials: Dockerfile, docker-compose.yml, Terraform configs, CloudFormation templates, database init scripts, and `.env` files committed to version control. For each file, count every hardcoded credential pattern: `postgres:postgres`, `root:root`, `admin:admin`, `sa:password`, `password=`, `SECRET_KEY=sk_live_`, or any literal password/key value (not a `${VAR}` reference). Before evaluating, quote the actual credential lines found.
- **Pass criteria:** Exactly 0 default or hardcoded credentials found across all infrastructure files examined. All credentials (at least 1 must exist) are sourced from environment variable references (`${VAR}`, `process.env.VAR`, `var.name`) or secure secret management services. Report: "Scanned X files, found 0 hardcoded credentials, Y environment variable references."
- **Fail criteria:** At least 1 hardcoded username/password or API key found in infrastructure configs, Dockerfile, or application code. Do NOT pass when credentials appear as defaults with an override option (e.g., `POSTGRES_PASSWORD=${DB_PASS:-postgres}` still contains a hardcoded fallback).
- **Skip (N/A) when:** No infrastructure files exist (no Dockerfile, no docker-compose, no Terraform, no CloudFormation, no `.env` files — fully managed PaaS with no credential configuration).
- **Detail on fail:** List all locations where default credentials were found. Example: `"docker-compose.yml line 8 contains POSTGRES_PASSWORD=postgres. Dockerfile line 12 contains ENV STRIPE_SECRET_KEY=sk_live_hardcoded. 2 hardcoded credentials found in 2 files."`
- **Remediation:** Remove all default credentials and replace with environment variables. Example:

  ```dockerfile
  # Before (insecure)
  ENV POSTGRES_USER=postgres
  ENV POSTGRES_PASSWORD=postgres

  # After (secure)
  ENV POSTGRES_USER=${DB_USER}
  ENV POSTGRES_PASSWORD=${DB_PASSWORD}
  ```

  ```yaml
  # docker-compose.yml
  services:
    db:
      environment:
        POSTGRES_USER: ${DB_USER}
        POSTGRES_PASSWORD: ${DB_PASSWORD}
        POSTGRES_DB: ${DB_NAME}
  ```

  For Terraform:
  ```hcl
  resource "aws_db_instance" "main" {
    username = var.db_username  # from tfvars, not hardcoded
    password = random_password.db.result
  }
  ```

  Use a secrets manager (AWS Secrets Manager, Supabase Vault, GitHub Secrets) for production credentials. Never commit secrets to version control — use `.gitignore` and `.env.local`.

## External references

- pci-dss Req 2.1
- pci-dss Req 8.3
- cwe CWE-1188
- owasp A05
- cwe CWE-798

Taxons: cryptography-and-secrets, regulatory-conformance

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