# HSTS（HTTP 严格传输安全）是什么？定义、例子与常见误区

> HSTS 是一个 HTTP 响应头，告诉浏览器在指定时间内只通过 HTTPS 访问该站点，并且遇到证书错误时不允许用户继续访问。

Source: https://ssl.sh/zh/glossary/hsts/
Last updated: 2026-11-10

HSTS 由 [RFC 6797](https://www.rfc-editor.org/rfc/rfc6797) 定义。浏览器通过有效的 HTTPS 连接收到 `Strict-Transport-Security` 响应头后，会在 `max-age` 秒内把该主机记为 HSTS 主机：期间所有指向它的 `http://` 链接都会在浏览器内部改写成 `https://` 再发出；遇到证书错误时直接拦截，不再给“继续访问”的选项。通过明文 HTTP 下发的这个头会被忽略。

## 为什么重要
服务器端的 HTTP→HTTPS 跳转仍然留下了第一个明文请求，[SSL 剥离](https://ssl.sh/zh/glossary/ssl-stripping/)攻击利用的正是它。HSTS 让除首次访问外的每次访问都不再发出这个明文请求，也让持无效证书的中间人从“用户点一下就能继续”变成彻底打不开。面板里的“强制 HTTPS”开关一般只是添加 301 跳转规则，不等于 HSTS。`includeSubDomains` 会把策略扩展到所有子域名，威力很大，但任何仍只支持 HTTP 的子域名都会因此无法访问。想连首次访问也保护住，需要加入 [HSTS 预加载](https://ssl.sh/zh/glossary/hsts-preload/)列表。

## 例子
```nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
```

```bash
curl -sI https://example.com | grep -i strict-transport-security
```

建议先用较短的 `max-age`（例如 300）确认所有子域名都能走 HTTPS，再逐步调大。在 Chrome 开发者工具里，HSTS 升级显示为 307 Internal Redirect，请求根本没有发到网络上。

## 常见误区
- **HSTS 能保护首次访问。** 不预加载的话，浏览器第一次访问前还没见过这个头，首个请求仍可能被劫持。
- **在 HTTP 响应里加上这个头就行。** 浏览器会忽略明文 HTTP 下发的 HSTS，必须通过证书有效的 HTTPS 下发。
- **HSTS 和 HPKP 一样会锁定证书。** HSTS 只强制使用 HTTPS，不关心用的是哪张证书。真正锁定公钥的 [HPKP](https://ssl.sh/zh/glossary/hpkp/) 已在 Chrome 72 中移除。

## 相关术语

- [HSTS 预加载](https://ssl.sh/zh/glossary/hsts-preload/): HSTS 预加载是内置在浏览器中的一份域名列表，列表内的域名始终通过 HTTPS 访问，连首次访问、尚未收到 HSTS 头之前也受保护。
- [SSL 剥离](https://ssl.sh/zh/glossary/ssl-stripping/): SSL 剥离是一种中间人攻击，攻击者截获本应把用户引向 HTTPS 的跳转或链接，让用户一直停留在明文 HTTP 上。
- [HTTPS](https://ssl.sh/zh/glossary/https/): HTTPS 是在 TLS 加密连接之上传输的 HTTP，默认使用 443 端口，使网页内容、Cookie 和表单数据被加密，并验证服务器身份。
- [混合内容](https://ssl.sh/zh/glossary/mixed-content/): 混合内容是指通过 HTTPS 加载的页面中，部分脚本、图片、iframe 等子资源仍通过明文 HTTP 加载，削弱了整个页面的安全性。
- [中间人攻击](https://ssl.sh/zh/glossary/man-in-the-middle/): 中间人攻击是指攻击者暗中插入通信双方之间，转发并可能篡改流量，而双方都以为自己在直接和对方通信。
- [HPKP](https://ssl.sh/zh/glossary/hpkp/): HPKP 是 RFC 7469 定义、现已废弃的 HTTP 响应头，要求浏览器只在证书链包含指定公钥时才接受该网站。
