HSTS (HTTP 严格传输安全)
定义
HSTS 是一个 HTTP 响应头,告诉浏览器在指定时间内只通过 HTTPS 访问该站点,并且遇到证书错误时不允许用户继续访问。
HSTS 由 RFC 6797 定义。浏览器通过有效的 HTTPS 连接收到 Strict-Transport-Security 响应头后,会在 max-age 秒内把该主机记为 HSTS 主机:期间所有指向它的 http:// 链接都会在浏览器内部改写成 https:// 再发出;遇到证书错误时直接拦截,不再给“继续访问”的选项。通过明文 HTTP 下发的这个头会被忽略。
为什么重要
服务器端的 HTTP→HTTPS 跳转仍然留下了第一个明文请求,SSL 剥离攻击利用的正是它。HSTS 让除首次访问外的每次访问都不再发出这个明文请求,也让持无效证书的中间人从“用户点一下就能继续”变成彻底打不开。面板里的“强制 HTTPS”开关一般只是添加 301 跳转规则,不等于 HSTS。includeSubDomains 会把策略扩展到所有子域名,威力很大,但任何仍只支持 HTTP 的子域名都会因此无法访问。想连首次访问也保护住,需要加入 HSTS 预加载列表。
例子
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
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 已在 Chrome 72 中移除。