# TLS / HTTPS

> Serve over HTTPS, redirect HTTP to HTTPS, and configure HSTS with preload and includeSubDomains. Agents downgrade trust on insecure origins.

Cette vérification représente 5 % du score.

*Ces guides de correction sont rédigés en anglais.*

<a id="invalid-url"></a>

## Invalid URL

Pass a fully qualified URL including scheme: `npx ax-audit https://your-site.com`. Bare hostnames like `your-site.com` are rejected.

---

<a id="no-https"></a>

## Site not served over HTTPS

Your site responds to HTTP only. AI crawlers and most agents refuse plaintext origins.

- **Free option:** [Let's Encrypt](https://letsencrypt.org) + [Certbot](https://certbot.eff.org) on your server, or your hosting provider's built-in TLS (Vercel, Netlify, Cloudflare, Render, Fly.io all give it for free).
- **Cloudflare Universal SSL:** proxy your domain through Cloudflare for instant HTTPS.
- **Self-hosted:** Caddy auto-provisions and renews certificates with zero config.

---

<a id="no-redirect"></a>

## HTTP does not redirect to HTTPS

A request to `http://your-site.com` returned content over plain HTTP instead of redirecting. Agents may cache the insecure variant.

```
# Nginx
server {
  listen 80;
  server_name your-site.com www.your-site.com;
  return 301 https://your-site.com$request_uri;
}

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

# Caddy
http://your-site.com {
  redir https://your-site.com{uri} permanent
}
```

---

<a id="redirect-unknown"></a>

## Redirect could not be verified

ax-audit got an unexpected response from the HTTP endpoint and couldn't determine the redirect behavior. Test manually:

```
curl -I http://your-site.com
# Expected: HTTP/1.1 301 Moved Permanently
#           Location: https://your-site.com/
```

---

<a id="no-hsts"></a>

## No HSTS header

`Strict-Transport-Security` instructs browsers and agents to use HTTPS for all future requests for a fixed period. Without it, the very first connection on a new device can still be downgraded.

```
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
```

```
# Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

# Express
app.use((req, res, next) => {
  res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
  next();
});

# Vercel (vercel.json)
{
  "headers": [{
    "source": "/(.*)",
    "headers": [{
      "key": "Strict-Transport-Security",
      "value": "max-age=31536000; includeSubDomains; preload"
    }]
  }]
}
```

---

<a id="hsts-no-maxage"></a>

## HSTS missing max-age

Your HSTS header has no `max-age` directive; without it the header is effectively ignored. Set a numeric value in seconds:

```
Strict-Transport-Security: max-age=31536000
```

---

<a id="hsts-short"></a>

## HSTS max-age too short

A `max-age` below ~6 months is too short to provide meaningful protection. The browser preload list requires **at least 1 year** (`31536000` seconds).

Recommended values: `max-age=63072000` (2 years) for production, `max-age=300` only while testing.

---

<a id="hsts-no-subdomains"></a>

## HSTS missing includeSubDomains

`includeSubDomains` applies HSTS to `api.your-site.com`, `docs.your-site.com`, etc. Without it, an attacker can downgrade `http://api.your-site.com` even when the apex is locked to HTTPS.

> **Caveat**
>
> Verify
>
> every
>
>  subdomain you own already serves HTTPS before enabling this flag. Once HSTS is cached by a client, an unreachable subdomain stays unreachable for the entire
>
> max-age
>
>  period.

---

<a id="hsts-no-preload"></a>

## HSTS missing preload directive

Adding `preload` to the HSTS header signals you want to be added to the [browser preload list](https://hstspreload.org): a hard-coded list of HTTPS-only domains shipped with Chromium, Firefox, Safari, and Edge.

After adding the directive and confirming the preload requirements, submit the domain at [hstspreload.org](https://hstspreload.org).

---

<a id="hsts-preload-invalid"></a>

## HSTS preload not eligible

The `preload` directive is set but the header doesn't satisfy the preload list requirements. To be eligible:

- `max-age` must be at least `31536000` (1 year).
- `includeSubDomains` must be present.
- `preload` must be present.
- The apex domain must redirect from HTTP to HTTPS.
- All subdomains must serve HTTPS.

Verify your status at [hstspreload.org](https://hstspreload.org).

---

Représentation Markdown de https://axrush.com/guides/tls-https
