2025 年跨站点 WebSocket 劫持利用

admin 2025年4月19日00:20:54评论1 views字数 5592阅读18分38秒阅读模式
2025 年跨站点 WebSocket 劫持利用
2025 年跨站点 WebSocket 劫持利用

在 Include Security 进行客户评估期间,我发现了一些我最感兴趣的发现,它们利用了跨站 Websocket 劫持 (CSWSH) 漏洞。然而,回顾过去的发现,我意识到其中一些漏洞如今并非在所有浏览器中都能正常工作。这是由于浏览器在跨域请求方面的基础安全性有所改进。这些改进包括第三方 Cookie 限制/全面 Cookie 保护以及私有网络访问。CSWSH 是这些功能的一个偶然牺牲品,因此除了这篇优秀的入门文章中略有提及外,我找不到太多关于 CSWSH 日益增加的限制的讨论。

这篇博文探讨了当前浏览器缓解措施的现状,这些措施使 CSWSH 更难被利用。我们将结合过去发现的三个案例研究,探讨哪些攻击至今仍然有效。

CSWSH 回顾

简单回顾一下 CSWSH。该漏洞的出现是因为 WebSocket 未受到最重要的浏览器安全机制——同源策略 (SOP) 的保护。默认情况下,由于缺乏 SOP 保护,恶意网站可以向运行 WebSocket 服务器的目标网站建立 WebSocket 连接。一个典型的例子是:用户浏览到 attack.com,在 attack.com 上运行的客户端代码会向 bank.com 建立 WebSocket 连接,浏览器会附加用户用于向 bank.com 进行身份验证的 cookie。这样,attacker.com 就可以伪装成用户向 bank.com 发送任意 WebSocket 消息。

其影响类似于跨站请求伪造 (CSRF) 攻击,但由于它是双向的,因此威力更大:恶意网站也可以读取恶意请求的响应。通常情况下,CSRF 攻击无法读取服务器的响应——除非目标服务器支持跨域资源共享 (CORS) 请求、允许包含凭据,并且配置错误,导致 Access-Control-Allow-Origin 响应标头中显示攻击者控制的来源。

CSWSH缓解措施

缓解 CSWSH 的终极方法是 WebSocket 服务器首先检查 WebSocket 握手请求的来源。如果请求并非来自可信且符合预期的来源,则 WebSocket 握手应该失败。“WebSocket 中缺少来源验证”有其自己的常见弱点枚举CWE-1385。

CSRF 攻击通常通过在请求 HTTP 标头中附加伪随机 CSRF 令牌来解决。服务器可以将标头值与存储在 Cookie 中的 CSRF 令牌进行比较(双重提交 Cookie 模式)。但由于 WebSocket 协议的奇特之处,无法设置任意标头,因此在 WebSocket 握手中很难实现这一点。有一些解决方法,例如将令牌放入Sec-WebSocket-Protocol 标头中,或在第一个 WebSocket 消息中进行身份验证。

CSWSH 先决条件

CSWSH 攻击要想奏效,需要满足以下几个先决条件:

  • 1)应用程序使用基于 cookie 的身份验证

  • 2)身份验证 cookie 设置为 SameSite=None

  • 3)WebSocket 服务器不验证 Websocket 握手请求的来源(并且不使用其他方式来验证请求的来源,例如在第一个 WebSocket 消息中进行身份验证)。

这似乎有很多事情需要协调,但 CSWSH 比我预想的更常见。如果我不得不推测的话:

  • 1)与令牌身份验证相比,Cookie 仍然相当流行。

  • 2)身份验证服务通常跨域运行,强制会话 Cookie 使用 SameSite=None 并依赖 CSRF 令牌作为抵御 CSRF 的主要机制,而这些机制不适用于 WebSocket 握手。

  • 3)Node.js 和其他常见 Web 应用框架的 ws 库不强制验证来源。

缓解措施

现在,让我们讨论一下当前的浏览器安全措施,以及这些措施如何使 CSWSH 攻击比以往更难实现。我们将介绍三种现有的可以预防 CSWSH 攻击的缓解措施,并在每种措施之后提供一个简短的案例研究,描述这些缓解措施如何影响 CSWSH 的可利用性。

默认 SameSite=Lax

SameSite=Lax 是长期以来有效的浏览器默认设置,会影响 CSWSH 攻击。如果 Cookie 上未明确配置 SameSite 设置,则 Chrome自 2020 年起已将其默认配置为 SameSite=Lax。SameSite =Lax 意味着浏览器仅会在跨站请求中发送由用户顶级导航(例如点击链接)引起的 GET 请求的 Cookie。

这大大增加了 CSRF 和 CSWSH 攻击的默认难度。需要注意的是,并非所有浏览器都默认设置了 SameSite=Lax。Firefox尝试过,但太多网站无法使用,因此 Firefox 更倾向于使用下文所述的 Total Cookie Protection。Safari 默认也不使用 SameSite=Lax ,但与 Firefox 类似,它也会阻止第三方 Cookie。基于 Chromium 的 Microsoft Edge 也遵循与 Chrome 相同的行为。

由于 SSO 登录在推出期间出现故障,Chrome 在 2020 年推出了一项临时措施,使默认的 SameSite=Lax 与后端应用程序明确设置为 SameSite=Lax 的 Cookie 的工作方式略有不同。对于隐式 SameSite=Lax,在发出 Cookie 后有两分钟的宽限期,在此期间仍会通过顶级跨站点 POST 请求发送 Cookie。正如PortSwigger 所述,在某些情况下,这可以绕过 SameSite 保护。我已验证这两分钟的宽限期在 Chrome 和 Firefox 中仍然存在。但是,它不适用于 CSWSH 攻击,因为 WebSocket 握手不是顶级 POST 请求。因此,需要将 SameSite 明确设置为 None 才能使 CSWSH 攻击起作用,SameSite 的其他任何值都不允许 CSWSH 运行。

案例研究 A

这是我在 2021 年针对一个网站进行的攻击,该网站实现了一个用于更改文档的 WebSocket API。会话 Cookie 没有设置 SameSite 属性。当时,这在 Firefox 中启用了 CSWSH 攻击,但在 Chrome 中则无法启用,因为默认情况下 SameSite=Lax。攻击者可以使用 CSWSH 对用户文档进行任意修改。我们发现该攻击时,攻击有效,但如今由于全面 Cookie 保护,该攻击在 Firefox 中也不再有效。

那么什么是 Total Cookie Protection?

过去几年,Firefox 一直在锁定其“增强型跟踪保护”功能。目前尚不清楚具体时间,但在 2022-2024 年的某个时候,“全面 Cookie 保护”已默认为所有用户启用,这对于阻止 CSWSH 非常有效。

全面 Cookie 保护的工作原理是将 Cookie 隔离到创建它们的网站。本质上,每个网站都有各自的 Cookie 存储分区,以防止第三方将用户的浏览历史记录关联在一起。这样做的目的是防止在网站 A 上加载的 tracker.com 脚本设置可被网站 B 上加载的 tracker.com 脚本读取的 Cookie。

它还具有停止基于 Cookie 的 CSWSH 的副作用。恶意站点无法使用用户的 Cookie 成功进行跨站点 WebSocket 握手,因为该 Cookie 位于当前 Cookie 存储分区之外。即使 Cookie 配置为 SameSite=None,此情况也适用。

可以在 Firefox 的浏览器隐私设置中禁用全面 Cookie 保护,方法是选择“增强跟踪保护”的“自定义”模式,然后取消选中 Cookies 设置或更改为旧的默认“跨站点跟踪 cookies”。

2025 年跨站点 WebSocket 劫持利用

请注意,谷歌多年来一直宣布将在 Chrome 中默认屏蔽第三方 Cookie,但由于各种原因一直拖延。最新目标是2025 年初,但他们在 2024 年 7 月更改了计划。不过,在“隐私和安全”设置中配置起来很简单,并且此设置在隐身模式下默认启用。某些发行版,尤其是 Debian Linux 上的 Chromium,默认设置为“屏蔽第三方 Cookie”。

2025 年跨站点 WebSocket 劫持利用

案例研究 B

此次攻击针对的是一个包含 GraphQL API 和 SameSite=None Cookie 的大型 Web 应用程序。由于服务器强制使用 application/json Content-Type,从而触发浏览器的预检请求,因此无法直接针对 GraphQL API 发起 CSRF 攻击。然而,GraphQL API 也可以通过 WebSocket 调用。WebSocket 存在 CSWSH 漏洞,第三方攻击者可以进行任意 API 调用,包括所有帐户操作,例如删除用户帐户。

由于 Total Cookie Protection,此漏洞现在在默认 Firefox 中无法利用,但目前在默认 Chrome/Edge 中仍可被利用。

专用网络访问

我们已经讨论了两种典型的 CSWSH 场景;现在来看一下在客户评估中遇到的一个比较不常见的场景。我们先从这个案例开始,因为它提供了不使用 Cookie 进行身份验证的情况的背景信息。

案例研究 C

此次攻击针对的是一台带有摄像头的网络设备。其设计理念是,同一网络上的用户无需进一步身份验证即可访问摄像头并执行有限的配置。位于同一私有网络中的用户被视为已完成身份验证(无需 Cookie)。该设备添加了一个易受 CSWSH 攻击的 WebSocket API。现在,互联网上的恶意网站可以通过连接到私有网络的目标用户的浏览器,从该设备流式传输视频并进行配置。

在审查针对私有 IP 地址上的 WebSocket 服务器的这次攻击时,我预计由于私有网络访问(显然自 Chrome 130 开始强制执行,但我发现在 Debian Linux 上的 Chromium 134 中默认情况下并未强制执行),它在最新版本的 Chrome 中不再起作用。

私有网络访问规范承认,越来越多的服务在用户的本地主机及其私有网络上运行,并描述了一种类似于 CORS 的控制机制,以防止公共互联网资源向私有资源发出未经批准的请求。例如,请参阅这篇针对 Tailscale 的精彩文章。

在私有网络访问规范中,IP 地址空间分为三种类型:公共、私有和本地。从更公共的地址空间向更私有的地址空间发出的请求(即使是 GET 请求)都会触发预检 OPTIONS 请求,该请求会附加由 Chrome 附加的 Access-Control-Request-Private-Network: true 标头,并且必须在响应中收到相应的 Access-Control-Allow-Private-Network: true 标头,主请求才能发送。

2025 年跨站点 WebSocket 劫持利用

然而,我发现针对私有 IP 的 CSWSH 攻击不受私有网络访问 (Private Network Access) 的影响。在我的测试中,尝试在 Chrome 中向本地主机地址发送 CSRF 攻击失败,但向更多私有 IP 开放 WebSocket 却没有问题。进一步思考后发现,这很有道理,规范中也提到了这一点,因为私有网络访问使用 CORS 预检请求作为保护方法,而 WebSocket 不遵循 SOP,因此不使用预检请求。

测试

为了验证以上所有观点,我制作了一个小型演示应用程序,源代码位于https://github.com/IncludeSecurity/cswsh-demo

一个小型 NodeJS Express 服务器在访问 / 路由时会设置 SameSite=None 的 cookie。该服务器还公开了一个 POST / 路由和一个 WebSocket 处理程序,如果在请求中发现 cookie,它们都会记录下来。

2025 年跨站点 WebSocket 劫持利用

然后将 WebSocket 服务器和演示页面托管在不同的 HTTPS 域中,并在不同的浏览器上尝试请求,以验证不同类型的 CSRF 和 CSWSH 攻击是否成功。添加了 /reflected 端点,以触发针对具有私有网络访问权限的私有 IP 尝试 CSRF 时特有的错误,否则 DevTools 中会显示通用的 CORS 错误。

请注意,检查 DevTools 中的 WebSocket 请求可能会产生误导——在 Chrome 中,WebSocket 握手时,DevTools 中并不总是会显示 Cookie!链接问题中一位 Chromium 开发者指出:“Cookie 标头附加在网络代码的较低层,因此 DevTools 并不总是包含所有内容。普通的 HTTP 请求会在 DevTools 中显示 Cookie,包括 HttpOnly Cookie,因为它们涉及不同的 Cookie 报告路径,会将原始标头直接发送到 DevTools。”

结论

总结一下:

  • SameSite=Lax 是 Chrome 中 cookie 的默认设置,对于 CSWSH 来说是一个不错的缓解措施,因此 CSWSH 需要 SameSite=None 会话/身份验证 cookie。

  • 虽然 Firefox 默认不应用 SameSite=Lax,但 Firefox 的 Total Cookie Protection 似乎可以完全缓解 CSWSH 的问题。

  • Chrome 团队多年来一直在讨论类似的第三方拦截技术,但至今仍未实现,并且正在研究其他方法。如果他们默认拦截第三方 Cookie,CSWSH 基本上就能被彻底淘汰。

  • Chrome 中的专用网络访问不会阻止 CSWSH 访问专用网络。

回顾这三个案例研究:

  • A) cookie 上未指定 SameSite 属性 -> 在任何主流浏览器中都不再起作用。

  • B) 典型的 CSWSH 与 SameSite=None cookie -> 在默认 Chrome 中有效,但在 Firefox 中无效。

  • C) CSWSH 针对私有 IP -> 仍然可以在所有浏览器上运行,尽管我最初预计它将不再在 Chrome 上运行。

对于防御者来说,在服务器端 WebSocket 握手处理程序中添加 Origin 检查仍然是防御 CSWSH 攻击的最佳方法。这一点至关重要,因为虽然浏览器的缓解措施正在缓慢改进,但并不能完全依赖它们。在适当的情况下,仍然可以针对默认 Chrome 浏览器执行 CSWSH,并且用户有可能运行配置为禁用“完全 Cookie 保护”等设置的浏览器。同样,依赖身份验证 Cookie 中的 SameSite=Lax 属性来防御 CSWSH 攻击并非理想选择。这些 Cookie 之后可能会在无关的代码更改中被更改为使用 SameSite=None,从而导致 CSWSH 漏洞被利用。

原文始发于微信公众号(Ots安全):2025 年跨站点 WebSocket 劫持利用

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年4月19日00:20:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2025 年跨站点 WebSocket 劫持利用https://cn-sec.com/archives/3976437.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息