# DMZ is properly configured between CDE and internet

- **Pattern:** `ab-001189` (`ecommerce-pci.network-security.dmz-configured`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001189
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001189)

## Why it matters

PCI-DSS 4.0 Req 1.3 requires that direct connections between the internet and CDE components are prohibited; Req 1.5 requires that risks from devices connecting to both untrusted networks and the CDE are addressed. Without a DMZ or filtering layer, internet traffic reaches CDE resources in one hop — a malformed webhook payload or HTTP flood hits the database network directly. CWE-668 (Exposure of Resource to Wrong Sphere) captures exactly this architecture gap. NIST SC-7 requires boundary protection at network perimeters. A WAF or reverse proxy in the DMZ also enforces rate limiting, which blocks credential-stuffing and payment enumeration attacks before they reach business logic.

## Severity rationale

Medium because the absence of a DMZ increases attack surface and removes a filtering layer that would otherwise block or rate-limit malicious traffic before it reaches CDE resources.

## Remediation

Place a WAF or reverse proxy (AWS WAF + ALB, Cloudflare, nginx) between the internet and your payment webhook receivers. Configure rate limiting at the DMZ layer, not in application code alone, so volumetric attacks are blocked before they consume compute resources.

```hcl
resource "aws_wafv2_web_acl" "dmz" {
  name  = "payment-dmz-waf"
  scope = "REGIONAL"
  default_action { allow {} }
  rule {
    name     = "RateLimit"
    priority = 1
    action   { block {} }
    statement {
      rate_based_statement {
        limit              = 2000
        aggregate_key_type = "IP"
      }
    }
    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "RateLimit"
      sampled_requests_enabled   = true
    }
  }
}
```

Document the DMZ boundary in `docs/cde-architecture.md` with a network diagram showing traffic flows from the internet through the DMZ to the application tier.

## Detection

- **ID:** `dmz-configured`
- **Severity:** `medium`
- **What to look for:** Count the number of filtering or proxy layers between internet and CDE. Look for at least 1 of: WAF (Web Application Firewall) configuration, reverse proxy (nginx, Caddy, ALB), API gateway, or dedicated DMZ security group/subnet in infrastructure code. Enumerate all internet-facing endpoints and trace the network path to CDE resources. Check for rate limiting configuration at the DMZ layer.
- **Pass criteria:** At least 1 filtering layer exists between internet and CDE (WAF, reverse proxy, API gateway, or dedicated DMZ subnet/security group). Internet-facing traffic passes through at least 1 validation/filtering step before reaching CDE resources. At least 1 rate limiting or request filtering rule is configured at the boundary. Report: "X filtering layers found between internet and CDE."
- **Fail criteria:** No DMZ or filtering layer evident (internet-facing services on same network as CDE with 0 intermediate filtering layers), or no WAF/proxy/gateway configured.
- **Skip (N/A) when:** All payment processing delegated to third-party with no direct internet-to-CDE traffic (no payment webhook handlers, no payment API routes).
- **Detail on fail:** Describe the architecture gap. Example: `"Payment webhook receiver and CDE database in same security group (app-sg). 0 filtering layers between internet and CDE."` or `"No WAF, reverse proxy, or API gateway configured. Internet traffic reaches CDE directly."`
- **Remediation:** Implement a DMZ. Use a reverse proxy or API gateway in the DMZ layer:

  ```hcl
  # AWS WAF + ALB in DMZ
  resource "aws_wafv2_web_acl" "dmz" {
    name  = "dmz-waf"
    scope = "REGIONAL"

    default_action {
      allow {}
    }

    rule {
      name     = "RateLimiting"
      priority = 1
      action {
        block {}
      }
      statement {
        rate_based_statement {
          limit = 2000
          aggregate_key_type = "IP"
        }
      }
      visibility_config {
        cloudwatch_metrics_enabled = true
        metric_name                = "RateLimiting"
        sampled_requests_enabled   = true
      }
    }
  }

  resource "aws_lb" "dmz" {
    name               = "dmz-alb"
    internal           = false
    load_balancer_type = "application"
    security_groups    = [aws_security_group.dmz.id]
    subnets            = aws_subnet.dmz[*].id
  }

  resource "aws_lb_target_group" "webhook" {
    name       = "webhook-targets"
    port       = 443
    protocol   = "HTTPS"
    vpc_id     = aws_vpc.main.id
    target_type = "ip"

    health_check {
      protocol = "HTTPS"
      path     = "/health"
    }
  }
  ```

---

## External references

- pci-dss Req 1.3
- pci-dss Req 1.5
- cwe CWE-668
- nist SC-7

Taxons: operational-readiness, regulatory-conformance

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