防范 HSTS 滥用

HTTP 严格传输安全(HSTS)是一种安全标准,它提供了一种机制,允许网站声明自己通过安全连接可访问,并告知网络浏览器如何获取该安全版本。遵守 HSTS 标准的网络浏览器还会阻止用户忽略服务器证书错误。

例如,Apple 在 iCloud.com 上使用 HSTS,因此,无论访问者是输入网址还是点击链接,任何时候尝试导航到不安全的地址“http://www.icloud.com”,他们都将自动重定向到“https://www.icloud.com”。HSTS 还会使网络浏览器在未来直接访问安全站点,即使使用了不安全的地址。这是一个很棒的功能,可以防止一个简单的错误导致用户处于危险状态,例如在未认证的连接上进行金融交易。

这有什么问题呢?

嗯,HSTS 标准描述了网络浏览器在被重定向到安全位置时应该记住,并在用户未来尝试不安全连接时自动替用户进行这种转换。这会创建可以存储在用户设备上并供以后引用的信息。而这可以用于创建一种可以被跨站点跟踪器读取的“超级 Cookie”。

HSTS 作为持久性跨站标识符(又称“超级 Cookie”)

寻求跟踪网站访问者的攻击者可以利用用户的 HSTS 缓存,在该用户设备上存储一位信息。例如,“通过 HTTPS 加载此域”可以表示 1,而 HSTS 缓存中没有条目则表示 0。通过注册大量域(例如,32 个或更多),并强制从这些域的受控子集加载资源,他们可以创建足够大的比特向量,以唯一标识每个网站访问者。

HSTS 作者在其规范的 第 14.9 节中认识到了这种可能性:

……HSTS 主机控制者可以通过编码信息到他们控制的域名中,并使这些用户代理在记录 HSTS 主机的过程中自然地缓存这些信息。这些信息可以通过巧妙构造和加载的网络资源被其他主机检索,从而导致用户代理向(编码域名的变体)发送查询。

首次网站访问时

  • 为访问者分配一个随机数,例如 8396804
  • 这可以表示为二进制值(例如,100000000010000000000100
  • 然后,跟踪脚本通过 HTTPS 对跟踪器控制的域进行子资源请求,每个跟踪标识符中的活动位对应一个请求。
    • https://bit02.example.com
    • https://bit13.example.com
    • https://bit23.example.com
    • ……等等。
  • 服务器对每个 HTTPS 请求使用 HSTS 响应头进行响应,这会将跟踪值缓存到网络浏览器中。
  • 现在,我们确保加载 bit02.example.com、bit13.example.com 和 bit23.example.com 的 HTTPS 版本,即使尝试通过 HTTP 加载。

后续网站访问时

  • 跟踪脚本通过 HTTP 加载 32 个不可见的像素,这些像素代表二进制数中的位。
  • 由于其中一些位(本例中的 bit02.example.com、bit13.example.com 和 bit23.example.com)已通过 HSTS 加载,它们将自动重定向到 HTTPS
  • 跟踪服务器在通过 HTTP 请求时传输一张图片,而在通过 HTTPS 请求时传输另一张图片。
  • 跟踪脚本识别不同的图片,将其转换为数字中的零(HTTP)和一(HTTPS)位,——您的唯一二进制值被重新创建,您被跟踪了!

由于平衡安全和隐私目标存在困难,试图缓解这种攻击具有挑战性。不恰当地缓解攻击也存在削弱重要安全保护的风险。

挑战

媒体上会周期性地讨论 HSTS 的隐私风险,将其作为一种理论上的跟踪向量(例如,[1][2][3])。由于缺乏 HSTS 协议实际恶意滥用的证据,浏览器开发者采取了谨慎态度,并尊重网站提供的所有 HSTS 指令。

最近我们发现,这种理论上的攻击开始针对 Safari 用户部署。因此,我们开发了一个平衡的解决方案,既能保护安全的网络流量,又能减轻跟踪。

Apple 的解决方案

HSTS 漏洞由两个阶段组成:初始跟踪标识符创建阶段和后续读取操作。我们决定对攻击的两端都采取缓解措施。

缓解措施 1:将 HSTS 状态限制为仅限于主机名,或顶级域 + 1

我们观察到跟踪站点构造长 URL,将数字编码到域名中的不同级别。

例如

https://a.a.a.a.a.a.a.a.a.a.a.a.a.example.com
https://a.a.a.a.a.a.a.a.a.a.a.a.example.com
https://a.a.a.a.a.a.a.a.a.a.a.example.com
https://a.a.a.a.a.a.a.a.a.a.example.com
https://a.a.a.a.a.a.a.a.a.example.com
https://a.a.a.a.a.a.a.a.example.com
https://a.a.a.a.a.a.a.example.com
…etc...

我们还观察到跟踪站点使用大量同级域名,例如

https://bit00.example.com
https://bit01.example.com
https://bit02.example.com
...etc...
https://bit64.example.com

遥测数据显示,攻击者会同时跨大量子域设置 HSTS。由于以这种方式使用 HSTS 不利于合法的用例,但却有助于跟踪,因此我们修改了网络堆栈,只允许为加载的主机名(例如,“https://a.a.a.a.a.a.a.a.a.a.a.a.a.example.com”)或顶级域 + 1(TLD+1)(例如,“https://example.com”)设置 HSTS 状态。

这可以防止跟踪器有效地跨大量不同比特设置 HSTS;相反,它们必须单独访问代表跟踪标识符中活动比特的每个域。虽然内容提供商和广告商可能会认为通过一个源进行一次重定向来设置多个比特所引入的延迟对用户来说是不可察觉的,但要求重定向到 32 个或更多域来设置标识符的比特对用户来说是可察觉的,因此对他们和内容提供商来说是不可接受的。WebKit 还限制了可以链接在一起的重定向数量,这为可以设置的比特数量设置了上限,即使延迟被认为是可接受的。

这解决了超级 Cookie 等式中设置的一方。

缓解措施 2:忽略对被阻止域的子资源请求的 HSTS 状态

我们修改了 WebKit,当来自我们阻止 Cookie 的域(例如不可见的跟踪像素)的非安全第三方子资源加载因动态 HSTS 而升级为认证连接时,我们忽略 HSTS 升级请求,只使用原始 URL。这使得 HSTS 超级 Cookie 变为只包含零的位字符串。

结论

在内部回归测试、我们的公共种子以及最终的公共软件发布期间收集的遥测数据显示,上述两项缓解措施成功阻止了 HSTS 超级 Cookie 的创建和读取,同时没有降低第一方内容的安全目标。我们认为它们符合最佳实践,并维护了 HSTS 提供的重要安全保护。我们已与 RFC 6797 的作者分享了缓解措施 1 的详细信息,并正在努力将该行为纳入标准。

然而,互联网是一个广阔的空间,充满了网络技术的独特和惊人用途。如果您认为这些新规则没有按预期工作,并且您有一个合理的理由,我们希望了解。请将反馈和问题发送至 web-evangelist@apple.com 或在 Twitter 上联系 @webkit,并向 WebKit 的 bug 跟踪器提交您遇到的任何 bug。

备注

  1. https://arstechnica.com/information-technology/2015/10/unpatched-browser-weaknesses-can-be-exploited-to-track-millions-of-web-users/
  2. http://www.businessinsider.com/super-cookies-hsts-security-private-2015-1,
  3. https://nakedsecurity.sophos.com/2015/02/02/anatomy-of-a-browser-dilemma-how-hsts-supercookies-make-you-choose-between-privacy-or-security/