首页/安全/漏洞与攻击面速查/HSTS 强制 HTTPS 传输
Web 漏洞原理与防护55 条

HSTS 强制 HTTPS 传输

HSTS 让浏览器在指定时间内强制使用 HTTPS 访问站点,缓解 SSL 剥离与降级;上线前提是 HTTPS 已稳定可用,建议从小 max-age 起步逐步加长,并评估子域覆盖。

漏洞与攻击面速查安全更新于 2026-10-13

HSTS 的作用与代价

HSTS 通过响应头让浏览器在一段时间内强制用 HTTPS 访问站点,阻断 SSL 剥离与协议降级:浏览器记住这条策略后,即使用户输入的是 http 链接也会本地改写为 https。它的生效前提是 HTTPS 已经稳定可用,因为一旦下发长期有效期,回退 HTTPS 或证书异常的站点会在有效期内无法访问。所以推荐从小有效期起步,确认稳定后再逐步加长。

基本信息

响应头Strict-Transport-Security,规范见 RFC 6797
主要参数max-age(秒)、includeSubDomains、preload
生效范围仅对浏览器生效,脚本与命令行客户端的行为不受影响
前置条件HTTP 入口 301 或 308 跳转到 HTTPS,证书链完整可信
上线策略先用 max-age=300 观察,稳定后逐步提高到一年
回退成本includeSubDomains 与 preload 无法快速撤回,风险最高

参数与影响

参数作用注意事项
max-age强制 HTTPS 的有效期(秒)常用一年,首次部署先从小值开始
includeSubDomains策略覆盖所有子域先确认全部子域都支持 HTTPS
preload写入浏览器预置列表申请条件严格,移除周期长
always(Nginx)让所有响应码都带该头不加则错误页可能缺头
301/308 跳转HTTP 入口强制跳转缺跳转时首次访问仍可能明文

Nginx 配置示例

Nginx 配置示例
# 生产稳定后:一年有效期并覆盖子域
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 首次部署先观察:max-age=300,确认没有 HTTP 依赖后再提高
# HTTP 入口必须跳转 HTTPS,否则浏览器第一次访问仍可能是明文
server {
    listen 80;
    server_name example.com;
    return 308 https://$host$request_uri;
}

要点

要点
HTTP 入口保持 301/308 跳转到 HTTPS
includeSubDomains 之前确认所有子域都支持 HTTPS(含内部系统与测试域)
preload 列表申请条件严格,评估后再操作
回退步骤要预演:万一需要下线 HTTPS,如何在有效期内恢复访问
上线后用 curl -I 与浏览器开发者工具确认响应头确实下发

典型使用场景

  • 站点启用 HTTPS 后的传输层加固
  • 合规与等级保护检查中的传输安全项
  • 修复 SSL 剥离类问题的验收项
  • 多子域统一治理时评估覆盖范围
  • CDN 与源站响应头一致性核查
  • 迁移域名或更换证书前的风险评估
一旦下发长期 HSTS,回退 HTTPS 会造成一段时间内全站不可访问。变更证书、域名或负载均衡之前先做规划,并明确回退方案与等待周期。
检查时注意头部是否在所有响应上生效:Nginx 的 add_header 不加 always 时,4xx 与 5xx 响应可能不带该头,错误页就成了降级可利用点。

易错点

  • 内部子域还有 HTTP 服务时就加 includeSubDomains:会把内部系统一起推向不可访问状态
  • 直接上一年有效期并申请 preload,出问题时无法在短时间内回退
  • add_header 不带 always,错误响应缺少头部,降级窗口依然存在
  • HTTP 入口未做跳转,浏览器首次访问仍是明文请求
  • CDN 与源站头部不一致,源站已加固但边缘节点未下发该头

数据来源与参考

  • RFC 6797(HSTS)
  • MDN Strict-Transport-Security 文档
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌