起因

前一段时间在工作中意外发现,CORS 并不适用于 Websocket 链接。 具体表现为,浏览器会忽略在websocket upgrade handshake过程中,所返回的 CORS 头。 比起类似的 CSRF 来说,感觉比较冷门,遂成文记录一下。

原因

CORS 下,对于 HTTP 请求的上下文校验,由浏览器一侧来执行,并决定是否终止请求。 但在 WebSocket 标准中,却选择了由服务端来全权处理这一部分逻辑,而浏览器则会自动带上用户所拥有的对应域下 Cookie。 这有些类似于 CSRF,但在 Websocket 世界中称之为 Cross-Site WebSocket Hijacking (CSWSH)

相关标准:https://tools.ietf.org/html/rfc6455#section-4.2.2

延伸阅读(CVE-2019-13611)

链接:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13611 链接:https://github.com/miguelgrinberg/python-engineio/issues/128

在 Python-EngineIO 框架中,服务端返回 CORS 相关的头,寄希望于浏览器来终止不正确的 websocket 链接,显然是不正确的 可能引发信息泄露,或服务器保持大量无效连接导致资源耗尽的问题。

这也是由这次意外发现,而报告的一个潜在的安全问题。