你的网站配好了 HTTPS,所有请求都加密。但你有没有想过:用户第一次访问时,如果在地址栏输入 rubyfun.cn(没加 https),浏览器会先尝试 HTTP。这个「先试 HTTP」的瞬间,就是攻击窗口——中间人可以拦截这个 HTTP 请求,伪装成你的网站。

HSTS(HTTP Strict Transport Security)就是为堵住这个窗口设计的。

降级攻击:为什么「支持 HTTPS」还不够

先理解威胁。假设你的站点同时支持 HTTP 和 HTTPS(为了兼容)。用户访问时的流程:

降级攻击:首次 HTTP 请求被中间人利用

  1. 用户输入 rubyfun.cn,浏览器默认发 HTTP 请求(因为没指定 https)。
  2. 中间人(公共 WiFi 的攻击者)拦截这个 HTTP 请求。
  3. 中间人伪装成服务器,和用户建立连接,同时自己去连真正的服务器拿数据。
  4. 用户以为自己连的是 rubyfun.cn,实际连的是中间人。整个过程中,用户到中间人这段是明文 HTTP,Cookie、密码全暴露。

这就是「降级攻击」——攻击者把本该走 HTTPS 的请求强行降级成 HTTP。即使你的服务器会把 HTTP 重定向到 HTTPS,那第一次的 HTTP 请求已经发出去了,中间人已经截获。

HSTS:让浏览器记住「必须 HTTPS」

HSTS 的原理是:让浏览器记住某个域名以后必须用 HTTPS,不再发 HTTP 请求

HSTS 的工作机制

服务器在 HTTPS 响应头里声明:

Strict-Transport-Security: max-age=31536000; includeSubDomains

浏览器看到这个头,记住「rubyfun.cn 这个域名,未来一年(31536000 秒)内必须用 HTTPS」。之后用户再输入 rubyfun.cn,浏览器直接走 HTTPS,根本不发 HTTP 请求——降级攻击的窗口被堵上了。

  • max-age=31536000:记住多久(一年)。建议设长,到期前刷新。
  • includeSubDomains:这个规则对子域名也生效。

这个机制的关键在于「浏览器记住」——不是每次都问服务器,而是浏览器本地记下了这个策略。所以即使中间人试图拦截,浏览器也不会发 HTTP 请求了。

HSTS 的盲点:第一次访问

HSTS 有个固有的盲点:第一次访问时,浏览器还没记住 HSTS 策略

第一次访问 rubyfun.cn,浏览器不知道这个域名该用 HTTPS,还是会发 HTTP 请求——这个瞬间仍然可能被降级攻击。HSTS 只在「浏览器已经记住策略之后」生效,第一次那个窗口它管不了。

这个盲点怎么堵?靠 HSTS Preload List

Preload List:浏览器内置的 HSTS 名单

为了让「第一次访问也安全」,浏览器厂商维护了一份 HSTS Preload List——一份内置在浏览器里的「必须用 HTTPS」的域名名单。你的域名提交进去并通过审核后,会被硬编码进 Chrome、Firefox 等浏览器。用户第一次访问时,浏览器查这份名单,发现 rubyfun.cn 在里面,直接走 HTTPS,连第一次的 HTTP 都不发。

HSTS Preload List:浏览器内置名单

加入 Preload List 的条件比较严格:必须全站 HTTPS(不能有任何 HTTP)、max-age 足够长(至少一年)、包含所有子域名。一旦加入,很难移除(因为已经硬编码进用户的浏览器了)。所以这是一个「慎重承诺」——加进去意味着你永远不能用 HTTP 了。

取舍与边界

HSTS 有几个实践要点:

  • HSTS 必须在 HTTPS 响应里声明。HTTP 响应里的 HSTS 头浏览器会忽略(否则中间人可以伪造「不要用 HSTS」)。所以你得先确保 HTTPS 配好,才能上 HSTS。
  • max-age 到期前要刷新。浏览器记的 HSTS 策略有有效期,到期就忘了。所以每次 HTTPS 响应都要带 HSTS 头,持续刷新有效期。
  • HSTS 和 301 重定向配合。常见配置:HTTP 请求 301 重定向到 HTTPS(兜住第一次),HTTPS 响应带 HSTS 头(堵住后续的降级)。加上 Preload List 堵住第一次。
  • 回退困难。一旦启用 HSTS(尤其加入 Preload),想回到 HTTP 很难——用户的浏览器会强制 HTTPS。启用前确认你能长期维护 HTTPS。

收束:HSTS 是 HTTPS 的安全补丁

HTTPS 保证了加密,但它防不住「用户第一次发 HTTP 被降级」。HSTS 让浏览器记住「必须 HTTPS」堵住后续,Preload List 堵住第一次。三者配合(HTTPS + HSTS + Preload),才是一套完整的「强制加密传输」方案。

下一篇是安全阶段的收尾,讲 Web 攻击的总览——XSS、CSRF、SQL 注入、点击劫持,这些攻击的原理和 HTTP 层面的防御。


关于十三Tech

我是十三,All in AI Agent 方向的架构师,专注 AI 工程实践。

我相信 AI 是程序员的最佳搭档,也希望帮助每一位开发者更好地驾驭 AI。

如果你想继续跟完这套「图解 HTTP」,欢迎关注公众号 「十三Tech」。后续会按 URL 与报文、连接与传输、缓存与协商、安全与边界、HTTP/2 与 HTTP/3 这条线更新。

十三Tech公众号二维码