使用 HSTS 和执行 301 重定向有什么区别?

信息安全 tls http hsts
2021-08-12 08:32:11

如果我已经完成了从所有 HTTP 内页到 HTTPS 的 301 重定向,为什么还要使用 HSTS?

4个回答

让我们先看一下 301 重定向的场景。受害者发送一个请求http://example.com(正如评论中指出的,这可能是因为 SSLStrip 或因为用户刚刚example.com在 URL 栏中输入并且浏览器默认为 HTTP)。如果没有中间人攻击,他们会收到 301 响应,并被重定向到https://example.com. 但如果有中间人,攻击者可以选择不发送 301,而是通过 HTTP 提供站点的(可能已修改)副本。

这里的弱点是建立了一个初始 HTTP 连接(没有 TLS),攻击者可以修改该流量。但是,如果您使用 HSTS,浏览器会知道(假设受害者之前访问过该站点)该页面应该始终通过 HTTPS 提供 - 不会发送任何 HTTP 请求,浏览器只会发送一个请求到https://example.com. 攻击者无法 MitM TLS 连接,因此攻击被阻止。

(浏览器缓存 301 响应的事实使这在实践中变得更加复杂。有关更多信息,请参阅bonsaiviking's great answerthis question。简短的故事是被缓存的 301 可能会有所帮助,但不会带你全部HSTS 的方式。)

HTTP 严格传输安全 (HSTS) 是为安全而设计的。HTTP 301 Moved Permanently 用于 URL 重定向。

301 重定向是部署 HTTPS 网站的重要组成部分。作为 HTTP 协议的一部分,它被比 HSTS 更多的浏览器支持。它是将纯文本连接升级到 HTTPS、更新搜索索引和避免链接失效的主要手段。

在许多情况下,这两种方法有相同的弱点:用户在浏览器中键入“example.com”时的初始请求是明文发送的。如果该初始请求是在具有活动中间人 (MITM) 的恶意网络上发出的,则可以拦截响应,并且连接不会升级到安全连接。

但是,HSTS 之所以重要,并且比标准 301 重定向有很大的安全性改进,原因有很多:

  • HSTS 覆盖整个域。301 重定向仅涵盖特定的 URI 路径。如果用户被重定向到example.com/,那么以后的请求example.com/somepage最初仍将使用 HTTP,并且必须再次重定向。使用 HSTS 的站点只需要一个请求即可覆盖整个站点。
  • HSTS 甚至可以使用初始 HTTPS 连接。301 重定向仅将明文 URI 映射到 HTTPS URI,因此直接访问 HTTPS 不会对后续访问提供任何保护。
  • HSTS 使用具有单独超时的单独缓存。301 缓存通常与浏览器的请求缓存相关联,它是为性能而设计的。如果您有一段时间不访问某个页面,它可能会从缓存中清除,以支持访问频率更高的站点。这个缓存的最大使用时间可能是几周或几个月。“站点无法正常工作”的常见修复方法是告诉用户“清除缓存”。所有这些都会让用户再次面临 MITM 威胁。HSTS 超时通常在几个月到几年的数量级,并且缓存通常是独立的,因此不能轻易或意外清除。
  • HSTS 可以由制造商预加载到浏览器中。谷歌使用他们的 Chrome 浏览器根据在网络抓取期间发现并直接提交给他们的程序的标头来执行此操作。对于预加载的网站,浏览器一开始就不需要通过明文访问;它总是可以假定为仅限 HTTPS。

首先,一些旧浏览器不支持 HSTS,所以你仍然需要将 HTTP 重定向到 HTTPS,secure在所有 cookie 上设置标志等。现在,话虽如此......

除了上面列出的原因之外,由于击败 SSLStrip 类型的攻击是 HSTS 的主要目的之一,HSTS 还可以防止另一种攻击,但简单的重定向却不能。

假设一个站点完全通过 HTTPS 访问。用户非常小心,只通过 HTTPS 请求此站点。不需要重定向。没有 HSTS,但也没有任何通过不安全 HTTP 链接到该站点的链接,因此该站点的所有流量都是加密的。

但是,假设该站点存在安全漏洞,它会将特定的 cookie(如果存在)反射到页面中而没有适当的转义(基于 cookie 的 XSS,很少见但几乎闻所未闻)。攻击者实际上无法读取(更不用说修改)HTTPS 流量,但他们确实想访问该 HTTPS 站点上的用户会话。因此,他们等待用户通过 HTTP 访问其他站点,并修改来自该站点的响应以包含一个不可见的请求(可能是脚本 src)到http://securesite.com/(您的仅 HTTPS 站点,但改为通过 HTTP)。接下来发生什么:

  • 如果站点在浏览器中具有活动的 HSTS 策略,则浏览器会自动重写请求,https://securesite.com/攻击者无法读取或修改任何流量。
  • 如果攻击者没有篡改但站点没有 HSTS,那么请求就会发出,得到一个 301 to https://securesite.com/,然后请求再次通过 HTTPS 发出。
    • 但是,securesite.com 的任何 cookie 但上面没有secure标记都将包含在初始不安全请求中。攻击者甚至可以通过被动窃听来读取它们。这很糟糕(这就是敏感 cookie 必须始终具有secure标志的原因,即使不应通过不安全的连接访问该站点)。
  • 但是,如果所有的 cookie 都是secure,那么这种攻击就毫无意义了。攻击者将不得不再次篡改。他们可以伪造或修改对不安全请求的响应。在这种特殊情况下,攻击者会Set-Cookie在响应中添加一个标头,在用户的浏览器中放置一个 cookie,该 cookie 将在未来通过 HTTP 或 HTTPS 向 securesite.com 发送请求时发送。

使用假设的基于 cookie 的 XSS 向量(或任何其他 cookie 植入攻击可能造成伤害的东西),攻击者成功地攻击了用户非常小心只能通过 HTTPS 访问的站点,只是因为它没有使用 HSTS并且有一个如果没有不安全的连接就无法利用的漏洞。

需要注意的关键是cookie的同源策略比其他地方的同源策略更宽松。也就是说,cookie 没有单一的安全通道,它们的来源相同:

Client ----Plain HTTP----> Server
Client ---------HTTPS----> Server

当然,可以设置安全标志,以便将 cookie 值设置为仅通过 HTTPS 传输。

例如

Set-Cookie: foo=bar; secure

Client --> HTTP  (no cookies)      --> Server
Client --> HTTPS (Cookie: foo=bar) --> Server

但是,服务器无法知道 cookie 是否设置了安全标志。

例如通过普通 HTTP

Set-Cookie: foo=bar

Client --> HTTPS (Cookie: foo=bar) --> Server

服务器将处于这种情况:

炒

因此,尽管服务器通过 HTTPS 设置的 cookie 不可嗅探,但 MITM 可以将自己的值注入“安全”会话。即使您没有纯 HTTP 服务也是如此:

Client ----Plain HTTP----> No service
Client ---------HTTPS----> Server

...因为 MITM 仍然可以向您的域生成纯 HTTP 请求并注入 cookie:

Client ----Plain HTTP----> MITM --> No service
Client ---------HTTPS-------------> Server

如果您的网站存在一些可能无法被利用的漏洞,这可能会导致一些攻击:

除了上述之外,ssltrip风格的攻击也可以在没有 HSTS 的情况下进行。sslstrip 在一定程度上依赖于用户没有注意到他们没有 HTTPS。

另请参阅此答案