第一个请求问题
HTTPS 在建立连接后对流量进行加密,但对 HTTP URL 的初始请求仍以明文形式发送。同网络上的攻击者可以拦截第一个请求,执行 SSL 分割攻击,将用户在整个会话中降级为 HTTP。
HTTP 严格传输安全 (HSTS) 会关闭此窗口。一旦浏览器收到 HSTS 标头,它就会自动将所有未来的 HTTP 请求升级为 HTTPS,并在无效时拒绝连接。
HSTS 的工作原理
服务器在 HTTPS 响应中发送 Strict-Transport-Security 标头:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
| 指令 | 描述 |
|---|---|
| 占位符_0 | 浏览器应记住仅使用 HTTPS 多长时间 |
| 占位符_0 | 将评估所有子域 |
| 占位符_0 | 浏览器预加载列表中包含信号 |
处理后,浏览器:
- 将域中的所有
http://链接重写为https://2.如果TLS握手失败或证书无效,则拒绝连接 - 在
max-age的持续时间服务器策略
在服务器上配置 HSTS
NGINX
server {
listen 443 ssl;
ssl_certificate /etc/ssl/certs/example.pem;
ssl_certificate_key /etc/ssl/private/example.key;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
}
即使在错误页面上生出标头,“始终”参数也能确保。
阿帕奇
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
###云耀
Cloudflare 通过仪表板实现 HSTS:SSL/TLS > 边缘证书 > HTTP 严格传输安全。您可以一键切换预加载和 includeSubDomains。Cloudflare 还提供 “No Sniff” 模式,可防止边缘的降级攻击。
Express/Node.js
const helmet = require("helmet");
app.use(helmet.hsts({
maxAge: 31536000,
includeSubDomains: true,
preload: true
}));
HSTS 预加载列表
max-age 指令仅在用户访问过您的网站一次后才作业。 HSTS 预加载列表嵌入到 Chrome、Firefox、Safari 和 Edge 中,对应始终使用 HTTPS 的域进行硬编码,从而完全消除了第一次请求漏洞。
要提交您的域名:
1.确保您的网站返回带有 preload 的有效 HSTS 标头
2. 转到hstspreload.org
3. 提交您的域名
包含预载的要求:
| 要求 | 详情 |
|---|---|
| 有效证书 | 所有子域上的 TLS |
| 占位符_0 | 至少 31536000(1 年) |
| 占位符_0 | 必填 |
| 占位符_0 | 出现在标题 |
| 方向 | HTTP → HTTPS 适用于所有请求 |
**警告:**预加载包含对于域来说是永久的。一旦接受,您就无法轻易地撤销您的域名从列表中删除。
测试 HSTS 部署
有几个工具可以验证您的 HSTS 配置:
# curl with headers
curl -sI https://example.com | grep -i strict-transport
# Security Headers
# https://securityheaders.com
# SSL Labs
# https://www.ssllabs.com/ssltest/analyze.html?d=example.com
# Using the HSTS check script
curl -s https://hstspreload.org/api/v2/check?domain=example.com
常见陷阱
| 问题 | 后果 | 修复 |
|---|---|---|
max-age 太短 | 保单墙壁厚度 | 设置为至少 1 年 |
缺少 includeSubDomains | 子域名不受保护 | 添加指令 |
| 仅 HTTP 站点提供 HSTS | 标题被忽略 | 仅通过 HTTPS 提供服务 |
| 内容 | 浏览器阻止不安全混合资源 | 审核所有http://引用 |
| 需准备好即可预加载 | 永久 HTTPS 要求 | 首先使用 max-age=0 进行测试 |
开发期间清除HSTS
要清除浏览器中缓存的HSTS策略:
- Chrome:
chrome://net-internals/#hsts→ 删除域名 - Firefox: 清晰域的浏览历史记录
- Safari: 清除首选项中的网站数据
作为开发人员,使用 max-age=0 来表示策略撤销:
Strict-Transport-Security: max-age=0
百年
HSTS是一个基本的安全标头,可以保证在首次访问后始终使用HTTPS,从而防止SSL分割和降级攻击。使用max-age=31536000、includeSubDomains和任选的preload对其进行配置以实现全面保护。始终使用安全检查器测试您的配置,并在开发过程中清除HSTS队列,曼哈顿锁定。

