安全头部HSTS

wen IT资讯 25

本文目录导读:

安全头部HSTS

  1. 核心作用
  2. 头部语法
  3. 如何配置(示例)
  4. HSTS Preload(预加载列表)
  5. 安全注意事项与最佳实践
  6. 常见问题

HSTS(HTTP Strict Transport Security,HTTP严格传输安全) 是一个非常重要的安全响应头部,用于强制浏览器只能通过 HTTPS 与服务器进行通信,从而有效防范中间人攻击、协议降级攻击和 Cookie 劫持。

以下是关于 HSTS 的详细说明,包括其作用、配置方法、注意事项以及常见问题。

核心作用

当你访问一个网站时,即使你在地址栏输入 http:// 或只输入域名,浏览器也可能会先尝试 HTTP 连接,如果网络环境不安全(如公共 WiFi),攻击者可以拦截这个请求,篡改内容或窃取信息,这就是 SSL 剥离攻击

HSTS 的作用就是:

  • 强制 HTTPS:浏览器一旦收到 HSTS 头部,在有效期内,绝不会再通过 HTTP 发送请求,而是直接在内部将所有 HTTP 链接重写为 HTTPS。
  • 拒绝无效证书:如果浏览器遇到证书错误(如过期、自签名、域名不匹配),HSTS 会阻止用户点击“继续访问”的选项,直接显示错误页面,防止用户绕过安全警告。

头部语法

服务器需要在 HTTPS 响应头中包含以下字段:

Strict-Transport-Security: max-age=<expire-time>; includeSubDomains; preload
  • max-age=<seconds> (必选):

    • 指定浏览器在未来多少秒内必须强制使用 HTTPS。
    • max-age=31536000 表示 1 年(365天)。
    • 注意:一旦设置,在到期前很难撤销(除非设置为 0)。
  • includeSubDomains (可选,强烈建议):

    • 告知浏览器该规则也适用于当前域名的所有子域名。
    • 如果设置在 example.com,则 api.example.comwww.example.com 也会被强制执行 HTTPS。
    • 风险:如果你的某个子域名不支持 HTTPS(old-blog.example.com),设置此选项会导致该子域名完全无法访问。
  • preload (可选,用于提交到 HSTS 预加载列表):

    • 表示允许该域名被提交到浏览器厂商维护的 HSTS 预加载列表
    • 一旦域名被硬编码进浏览器(Chrome、Firefox、Safari 等),用户在第一次访问时就会强制使用 HTTPS,无需等待首次响应头。

如何配置(示例)

Nginx

server 块中添加:

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

Apache

.htaccesshttpd.conf 中添加:

Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"

IIS (通过 web.config)

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Strict-Transport-Security" value="max-age=63072000; includeSubDomains; preload" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Express.js (Node.js)

const helmet = require('helmet');
app.use(helmet.hsts({
  maxAge: 63072000,
  includeSubDomains: true,
  preload: true
}));

HSTS Preload(预加载列表)

问题:普通 HSTS 存在一个“第一次访问”的漏洞,如果用户从未访问过你的 HTTPS 网站,第一次通过 HTTP 请求时,攻击者可以拦截它,阻止浏览器收到 HSTS 头部。

解决方案:向 hstspreload.org 提交你的域名,一旦审核通过,你的域名会被硬编码到 Chrome、Firefox、Safari、Edge 等浏览器的代码中,从此,浏览器在任何情况下都会直接使用 HTTPS 连接你的域名。

⚠️ 警告

  • 提交后难以移除:如果提交后你决定关闭 HTTPS,需要联系浏览器厂商,且可能需要等待数月甚至更久才能从列表中移除。
  • 需要满足条件:必须配置 max-age 至少为 1 年(31536000秒)、包含 includeSubDomainspreload 指令,并且所有子域名都必须支持 HTTPS。

安全注意事项与最佳实践

  1. 仅通过 HTTPS 发送:千万不要在 HTTP 响应中设置 HSTS 头部,因为 HTTP 请求本身就可以被篡改,设置无效。

  2. 从较低的 max-age 开始:如果你是第一次配置,先使用较短的 max-age(如 5 分钟 300 或 1 小时 3600),确保没有负面影响后,再逐步增加到半年(15768000)或一年(31536000)。

  3. 先别加 includeSubDomains

    • 确认所有子域名(包括 wwwapimail 等)都支持 HTTPS。
    • 如果不确定,先不加该选项,或者单独为子域名配置 HSTS。
  4. 小心 preload

    • 只有在你 100% 确定 再也不会回退到 HTTP 并且所有子域名都准备好时,才提交预加载,一旦提交,撤销极其困难。
  5. 配合 301 重定向

    确保 HTTP 到 HTTPS 的 301 永久重定向工作正常,否则用户无法从 HTTP 转换到 HTTPS,也就无法获取到 HSTS 头部。

  6. 使用浏览器检查

    • 打开浏览器开发者工具 (F12) -> 网络 (Network) 标签。
    • 点击一个 HTTPS 请求,查看响应头 (Response Headers) 中是否包含 Strict-Transport-Security

常见问题

Q:为什么我在 HTTP 响应中看不到这个头部? A:因为 HSTS 头部必须在 HTTPS 响应中发送。

Q:如果浏览器时间是错误的怎么办? A:浏览器会使用本地时间计算 max-age,如果用户时间大幅度跳跃(例如调整到未来),可能导致 HSTS 策略意外过期或提前生效。

Q:如何暂时关闭 HSTS? A:将 max-age 设置为 0,然后通过 HTTPS 访问一次,浏览器会清除该域名的 HSTS 策略,但如果你提交了 preload,这种方法无效,需要联系浏览器厂商。

Q:设置了 HSTS 后,网站突然打不开了? A:最常见的原因是:

  • includeSubDomains 覆盖了一个不支持 HTTPS 的子域名。
  • 证书配置错误。
  • 用户清除了 HSTS 缓存或时间错乱。
  • HSTS 是 HTTPS 的安全补充,而不是替代品。
  • 标准实践max-age=31536000; includeSubDomains; preload(仅当你有决心时加 preload)。
  • 核心作用:彻底消除 HTTP -> HTTPS 重定向过程中的风险,杜绝用户点击 SSL 证书错误提示的可能性。

合理配置 HSTS 是提升网站安全等级的重要一步,尤其是在处理登录、支付等敏感操作时。

上一篇CSRF token

下一篇CORS配置安全

抱歉,评论功能暂时关闭!