# All financial data transmissions use TLS 1.2+

- **Pattern:** `ab-001421` (`finserv-encryption.data-in-transit.tls-12-minimum`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001421
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001421)

## Why it matters

CWE-319 (cleartext transmission of sensitive information) is the direct consequence of missing or misconfigured TLS. Any financial data transmitted over HTTP — payment amounts, account identifiers, session tokens — can be intercepted by a network attacker via passive sniffing or active MITM without the user's knowledge. PCI-DSS 4.0 Req-4.2 explicitly forbids transmission of cardholder data over open public networks without strong cryptography, and specifically deprecates TLS 1.0 and 1.1. NIST SC-8 requires transmission confidentiality. A single HTTP payment API call, even in a test code path that reaches production, is a critical compliance and security failure under both frameworks.

## Severity rationale

Critical because TLS below 1.2 or missing HTTPS redirects expose financial data to passive network interception with no attacker authentication required — the attack is trivially automated.

## Remediation

Enforce HTTPS at the application boundary and set a minimum TLS version of 1.2 (prefer 1.3). In Next.js, add an HSTS header via `next.config.ts` and redirect HTTP at the middleware layer:

```typescript
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';

export function middleware(req: NextRequest) {
  if (req.headers.get('x-forwarded-proto') === 'http') {
    return NextResponse.redirect(
      `https://${req.headers.get('host')}${req.nextUrl.pathname}${req.nextUrl.search}`,
      301
    );
  }
  return NextResponse.next();
}
```

For self-managed nginx, set:
```nginx
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:TLS_AES_256_GCM_SHA384;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
```

Vercel and Netlify enforce TLS 1.2+ by default, but you still need HSTS headers for browsers to refuse future HTTP connections.

## Detection

- **ID:** `tls-12-minimum`
- **Severity:** `critical`
- **What to look for:** Count all server configurations and enumerate TLS version settings. Quote the actual `ssl_protocols` or TLS minimum version found. Count all HTTP endpoints and verify each redirects to HTTPS. Count all external API calls to payment processors and verify HTTPS usage. A TLS version below 1.2 does not count as pass — do not pass if TLS 1.0 or 1.1 is configured.
- **Pass criteria:** All HTTP endpoints redirect to HTTPS (or are HTTPS-only), AND minimum TLS version is 1.2 or higher in at least 1 server configuration. Count all payment API calls — at least 100% must use HTTPS. Report the count even on pass (e.g., "TLS 1.3 configured, 3 of 3 payment API calls use HTTPS, HSTS enabled").
- **Fail criteria:** HTTP served without redirect, OR TLS version below 1.2, OR any payment API call uses HTTP instead of HTTPS.
- **Skip (N/A) when:** Never — all financial data transmission must use TLS 1.2+.
- **Detail on fail:** `"TLS 1.1 configured — below TLS 1.2 minimum"` or `"2 of 5 HTTP endpoints lack HTTPS redirect"` or `"1 of 3 payment API calls uses HTTP"`
- **Cross-reference:** Check `finserv-encryption.pci-alignment.encryption-scan-verified` for TLS scan results, and `finserv-encryption.data-in-transit.certificate-validation` for certificate verification.
- **Remediation:**
  - **For Next.js/Node.js:**
    ```typescript
    // next.config.ts
    const nextConfig = {
      headers: async () => [
        {
          source: '/:path*',
          headers: [{ key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' }],
        },
      ],
    };
    ```
    Or in a middleware:
    ```typescript
    // middleware.ts
    export function proxy(req: NextRequest) {
      if (!req.nextUrl.protocol.startsWith('https')) {
        return NextResponse.redirect(`https://${req.headers.get('host')}${req.nextUrl.pathname}`);
      }
      return NextResponse.next();
    }
    ```
  - **For deployment (Vercel, Netlify):** HTTPS and TLS 1.2+ are enabled by default.
  - **For custom servers:** Configure TLS minimum version in your web server config:
    ```nginx
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ```

## External references

- cwe CWE-319
- owasp A02
- nist SC-8
- pci-dss Req-4.2
- external FFIEC-IT-Handbook-IS-TLS — https://ithandbook.ffiec.gov/it-booklets/information-security.aspx

Taxons: cryptography-and-secrets

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