> ## Documentation Index
> Fetch the complete documentation index at: https://docs.37audits.com/llms.txt
> Use this file to discover all available pages before exploring further.

# HSTS Preload Auditor

> Checks whether Strict-Transport-Security meets Chromium HSTS preload header requirements

<Info>
  **Security Auditor** — checks whether `Strict-Transport-Security` meets Chromium HSTS preload header requirements.
</Info>

<CardGroup cols={2}>
  <Card title="Security" icon="shield">
    Preload-ready HSTS locks browsers onto HTTPS for the host and all subdomains.
  </Card>

  <Card title="Compatibility" icon="lock">
    Header syntax follows RFC 6797; Chromium requires max-age ≥ 1 year, includeSubDomains, and preload.
  </Card>
</CardGroup>

This auditor fetches the audited HTTPS URL and inspects `Strict-Transport-Security`. It does **not** check HTTP→HTTPS redirects, certificate validity, or whether the host is already on the live Chromium preload list.

## How it works

The auditor judges Chromium [HSTS preload](https://hstspreload.org/#submission-requirements) readiness from the STS header on the audited URL:

1. **Parse** — requires an `https` URL with a hostname. Non-HTTPS URLs skip the fetch and warn. Invalid or empty URLs error.
2. **Fetch** — reads response headers with `HeadersCrawler`. All `Strict-Transport-Security` values are collected; RFC 6797 uses the first.
3. **Rules** — missing header, missing or low `max-age` (below `31536000`), missing `includeSubDomains`, and missing `preload` are separate FAILs. Multiple STS values are a WARNING.
4. **Aggregate** — `ERROR` wins, then `FAIL`, then `WARNING`; if every rule passes, the audit is `SUCCESS`.
5. **Specification pin** — every run emits `37A-HSTSPreloadAuditor-100` (`INFORMATION`) naming Chromium HSTS Preload submission requirements and [RFC 6797](https://www.rfc-editor.org/rfc/rfc6797) (2012-11), pinned to `https://hstspreload.org/#submission-requirements`. That check does not change overall status.

## What it audits

Every row maps to one `checkRule*` method and one `CheckCode`. `37A-HSTSPreloadAuditor-100` is emitted on every run, including fetch errors and non-HTTPS URLs. Directive FAILs (`401`–`404`) are skipped when the header itself is missing (`400`). CheckCode suffixes use status ranges: `100` information, `200` success, `300–399` warning, `400–499` fail, `500–599` error.

| CheckCode                                                         | Status        | When it fires                                                                                                                                                         | Recommendation                                                                                                                 |
| ----------------------------------------------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| <a id="37A-HSTSPreloadAuditor-100" />`37A-HSTSPreloadAuditor-100` | `INFORMATION` | Every run. Records that this auditor implements Chromium HSTS Preload submission requirements and RFC 6797 header syntax.                                             | This auditor implements Chromium HSTS Preload submission requirements; pin `https://hstspreload.org/#submission-requirements`. |
| <a id="37A-HSTSPreloadAuditor-301" />`37A-HSTSPreloadAuditor-301` | `WARNING`     | The URL scheme is not `https`.                                                                                                                                        | Use https\:// for `{url}`; HSTS preload cannot be audited over `{scheme}`.                                                     |
| <a id="37A-HSTSPreloadAuditor-300" />`37A-HSTSPreloadAuditor-300` | `WARNING`     | More than one `Strict-Transport-Security` header value was returned.                                                                                                  | Send a single Strict-Transport-Security header on `{url}`; RFC 6797 uses the first value (`{first}`).                          |
| <a id="37A-HSTSPreloadAuditor-400" />`37A-HSTSPreloadAuditor-400` | `FAIL`        | `Strict-Transport-Security` is absent or blank.                                                                                                                       | Add `Strict-Transport-Security: max-age=31536000; includeSubDomains; preload` on `{url}`.                                      |
| <a id="37A-HSTSPreloadAuditor-401" />`37A-HSTSPreloadAuditor-401` | `FAIL`        | The header is present but has no usable `max-age` directive.                                                                                                          | Add `max-age` ≥ 31536000 to `{header}` on `{url}`.                                                                             |
| <a id="37A-HSTSPreloadAuditor-402" />`37A-HSTSPreloadAuditor-402` | `FAIL`        | `max-age` is present and below 31536000 (skipped when `401` applies).                                                                                                 | Raise max-age on `{url}` from `{maxAge}` to at least 31536000 (header `{header}`).                                             |
| <a id="37A-HSTSPreloadAuditor-403" />`37A-HSTSPreloadAuditor-403` | `FAIL`        | The header is present but does not include `includeSubDomains`.                                                                                                       | Add includeSubDomains to the Strict-Transport-Security header on `{url}`.                                                      |
| <a id="37A-HSTSPreloadAuditor-404" />`37A-HSTSPreloadAuditor-404` | `FAIL`        | The header is present but does not include `preload`.                                                                                                                 | Add the preload token to the Strict-Transport-Security header on `{url}`.                                                      |
| <a id="37A-HSTSPreloadAuditor-500" />`37A-HSTSPreloadAuditor-500` | `ERROR`       | The URL is invalid or response headers could not be read.                                                                                                             | Retry the audit of `{url}`; verify the URL is reachable. Last error was `{error}`.                                             |
| <a id="37A-HSTSPreloadAuditor-200" />`37A-HSTSPreloadAuditor-200` | `SUCCESS`     | HTTPS response has a single preload-ready STS header. Message is `Strict-Transport-Security on "{url}" is "{header}" (max-age={maxAge}, includeSubDomains, preload).` | —                                                                                                                              |

## Output documentation

| Status          | Description                                          | Test logic                                                                                                                                             |
| --------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **SUCCESS**     | The HTTPS response sends a preload-ready STS header  | First `Strict-Transport-Security` value has `max-age` ≥ 31536000, `includeSubDomains`, and `preload` (`200`).                                          |
| **WARNING**     | Preload cannot be judged, or the header is ambiguous | Scheme is not https (`301`); more than one STS value (`300`). Multiple values can appear together with FAILs when the first header is incomplete.      |
| **FAIL**        | The header is missing or not preload-eligible        | Missing header (`400`); no usable `max-age` (`401`); `max-age` below 31536000 (`402`); missing `includeSubDomains` (`403`); missing `preload` (`404`). |
| **ERROR**       | The auditor could not read headers                   | Empty, blank, or invalid URL; fetch failure (`500`).                                                                                                   |
| **INFORMATION** | Specification pin                                    | Always emitted (`100`); does not change overall status.                                                                                                |

## Risks and considerations

### Preload is hard to undo

* Once a host is on the Chromium preload list, browsers refuse HTTP for that host and all subdomains until a removal request is processed.
* Do not add `preload` until every subdomain can serve HTTPS and you intend to submit the domain at [hstspreload.org](https://hstspreload.org/).

### Incomplete HSTS is not preload

* A header without `includeSubDomains` or `preload`, or with `max-age` under one year, is ordinary HSTS at best and is not eligible for the preload list.
* `max-age=0` signals HSTS removal and fails the preload minimum.

### What this auditor does not check

* Chromium also requires a valid certificate and an HTTP→HTTPS redirect on the same host. Use the Certificate and HTTP Redirect auditors for those.
* STS headers sent over HTTP are ignored by RFC 6797; this auditor will not fetch a non-https URL.
* Presence on the live Chromium preload list is not verified.
