# HTTPS is enforced

- **Pattern:** `ab-002521` (`site-health-check.security-posture.https-enforced`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002521
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002521)

## Why it matters

Serving over HTTP exposes every request to network-level eavesdropping and man-in-the-middle attacks — credentials, session cookies, and form data transit in plaintext. OWASP A02 (Cryptographic Failures) and NIST SP 800-53 SC-8 both cite unencrypted transport as a baseline failure. Beyond confidentiality, modern browsers mark HTTP pages as 'Not Secure', and Google penalizes them in search rankings. Sites that accept HTTP alongside HTTPS without redirecting give attackers a trivial downgrade path: intercept a single HTTP request, strip the redirect, and own the session. CWE-319 directly captures this: cleartext transmission of sensitive information.

## Severity rationale

Critical because plaintext HTTP exposes credentials, cookies, and form payloads to any network observer without requiring any exploit beyond passive interception.

## Remediation

Configure your server to redirect all HTTP traffic to HTTPS with a 301. On nginx, add this to the HTTP server block:

```nginx
server {
  listen 80;
  server_name example.com;
  return 301 https://$host$request_uri;
}
```

On Vercel, Netlify, and Cloudflare Pages, HTTPS redirect is enforced automatically at the edge — no config needed. For Apache, add to `.htaccess`:

```apache
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
```

Verify the redirect is active with `curl -sI http://yoursite.com | grep -i location`.

## Detection

- **ID:** `https-enforced`
- **Severity:** `critical`
- **What to look for:** Count the number of redirects in the chain returned by `curl -sI -L`. Check if the final URL after all redirects uses `https://`. If the initial URL used `http://`, verify that at least 1 redirect in the chain upgrades the scheme to HTTPS.
- **Pass criteria:** Final URL uses `https://` scheme after following all redirects. If the initial request was to an `http://` URL, the redirect chain must include at least 1 hop that upgrades to `https://`. Report the total number of redirects observed.
- **Fail criteria:** Final URL uses `http://`, or no redirect from HTTP to HTTPS exists.
- **Skip (N/A) when:** The target URL is a localhost or private IP address (127.0.0.1, 192.168.x.x, 10.x.x.x) where HTTPS is not expected.
- **Do NOT pass when:** The site accepts both HTTP and HTTPS without redirecting HTTP to HTTPS — even if you happened to request the HTTPS version, the HTTP version being accessible is a fail.
- **Report even on pass:** Report the redirect count and final URL: "HTTPS enforced — 1 redirect, final URL: https://example.com/."
- **Detail on fail:** Describe what was found. Example: `"Site serves over HTTP with no redirect to HTTPS"` or `"HTTP URL does not redirect to HTTPS — site accessible over both protocols"`
- **Remediation:** HTTPS encrypts traffic between the browser and server, preventing eavesdropping. Configure your server or hosting platform to redirect all HTTP requests:

  ```
  # .htaccess (Apache)
  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
  ```

  On Vercel, Netlify, and Cloudflare Pages, HTTPS is enforced automatically. For nginx, add `return 301 https://$host$request_uri;` to the HTTP server block.

## External references

- cwe CWE-319
- owasp A02
- nist SC-8

Taxons: cryptography-and-secrets

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