Hacker News Best

Developers don't understand CORS (2019)

8.5内容质量

TL;DR · AI 摘要

CORS机制被误解导致Zoom出现安全漏洞,正确配置可避免此类问题。

核心要点

  • Chrome浏览器实际上会遵循localhost服务器的CORS策略。
  • Zoom使用图片尺寸传递状态码以绕过CORS,导致安全漏洞。
  • 正确的做法是设置Access-Control-Allow-Origin和Content-Security-Policy头。

结构提纲

按章节快速跳转。

  1. 作者通过与不同水平的开发者合作,发现CORS机制被广泛误解。

  2. ·Zoom漏洞案例

    Zoom使用图片尺寸传递状态码以绕过CORS,导致安全漏洞。

  3. Chrome浏览器实际上会遵循localhost服务器的CORS策略。

  4. 正确的做法是设置Access-Control-Allow-OriginContent-Security-Policy头。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • CORS误解与Zoom漏洞
    • CORS机制
      • 浏览器遵循CORS策略
      • 绕过CORS的错误方法
    • Zoom漏洞
      • 使用图片尺寸传递状态码
      • 导致安全漏洞
    • 安全建议
      • 设置Access-Control-Allow-Origin
      • 设置Content-Security-Policy

金句 / Highlights

值得收藏与分享的关键句。

  • Chrome does respect CORS headers for localhost webservers.

    第 4 段

    ⬇︎ 下载 PNG𝕏 分享到 X
  • This will ensure that only Javascript running on the zoom.us domain can talk to the localhost webserver.

    第 6 段

    ⬇︎ 下载 PNG𝕏 分享到 X
  • By doing this, they opened Zoom up to a big vulnerability because not only can the Zoom website trigger operations in the native client and access the response, but every other website on the internet

    第 5 段

    ⬇︎ 下载 PNG𝕏 分享到 X
#CORS#前端#安全#Zoom
打开原文

开发者并不理解 CORS - Chris Foster

Chris Foster

博客 -

简介

-

演讲

开发者并不理解 CORS

2019 年 7 月 10 日 — Chris Foster

全栈咨询工作最棒的地方之一就是我可以与来自不同公司、不同规模和不同行业的众多开发者合作,他们拥有不同的技能水平。这让我有机会看到一些普遍存在的挑战。最近一个看起来很常见且相关的问题是:太多网页开发者并不理解 CORS 的工作原理。

内容分隔器

指出这一点似乎特别及时,因为最近 Zoom 存在一个漏洞。安全研究员 Jonathan Leitschuh 发现 Zoom 在本地机器上运行了一个监听 http://localhost:19421 的网页服务器。当你加载一个 Zoom 链接时,Zoom 的网站会向本地网页服务器发送请求,并让它打开本地的 Zoom 应用。这篇文章值得一读,但其中一些内容引起了我的注意:

我还发现,这个页面并没有使用常规的 AJAX 请求,而是从本地运行的 Zoom 网页服务器加载了一张图片。图片的不同尺寸决定了服务器返回的错误/状态码。你可以在这里看到这种 case-switch 逻辑。我问自己一个问题,为什么这个网页服务器会将数据编码在图片文件的尺寸中?原因是为了绕过跨域资源共享(CORS)。出于非常明确的原因,浏览器会明确忽略运行在 localhost 上的服务器的 CORS 策略。

最后一句话是错误的 — Chrome 会尊重运行在 localhost 上的网页服务器的 CORS 头信息。如果你是网页开发者,你可能在使用 Create React App 时遇到过这种情况,前端应用运行在一个端口,而后端 API 运行在另一个端口。你的应用会向 localhost 发起跨域请求,所有浏览器都支持这种操作。

这让我觉得 Zoom 可能需要快速推出这个功能,但并不理解 CORS。他们无法在浏览器不允许的情况下进行 AJAX 请求。于是,他们使用了这种图片技巧来绕过 CORS。通过这样做,他们让 Zoom 面临一个重大漏洞,因为不仅 Zoom 网站可以触发本地客户端的操作并访问响应,互联网上的任何其他网站也可以做到这一点。

那么,这个功能的安全实现方式应该是什么样呢?监听在 localhost:19421 上的网页服务器应该实现一个 REST API,并设置 Access-Control-Allow-Origin 头信息,其值为 https://zoom.us。这将确保只有运行在 zoom.us 域名上的 JavaScript 才能与本地网页服务器通信。此外,为了防止页面在后台自动打开 Zoom 会议,zoom.us 应该设置一个内容安全策略(Content Security Policy)头信息,以阻止在 iframe 中渲染。

这仍然存在一个漏洞,即任何页面都可以将你的浏览器重定向到一个你没有预期的 zoom.us 会议链接,但这是 Zoom 做出的用户体验决策,而不是软件漏洞。我个人认为,这种做法也是错误的。他们提到他们希望通过直接打开应用程序来改善用户体验,但好的用户体验设计的一个规则是,你的软件必须具有可预测性。

如果我在点击一个链接,我期望它不会突然让我将摄像头和麦克风权限提供给我不认识的人。Zoom 的做法打破了这种预期。即使他们出于用户体验的原因不希望使用内置浏览器弹窗,也请将这个弹窗放在应用内!Google Meet 就做得很好:

我不想偏离本文对 CORS 的关注。无论从用户体验的角度如何争论,运行一个本地主机上的 Web 服务器本身就是一个风险性很高的行为。它绝对不应该为互联网上的每一个网站提供访问特权功能(如安装软件)的权限。CORS 使你能够安全地实现这一点——不要绕过它!

我无法确定是否是由于对 CORS 的理解不足,导致 Zoom 以这种方式实现该功能。然而,我和一些人讨论过,我们都没有找到任何合理的理由来支持他们目前的实现方式。在 Reddit 上,lerunicorn 发现并建议说,Firefox 可能会阻止从安全来源到非安全来源的 XHR 请求,这可能解释了他们采用这种做法的动机。然而,当来源是 localhost 的时候,Firefox 是支持这种行为的。另外,原生应用可以生成一个唯一的自签名证书。或者,他们也可以使用浏览器扩展。无论哪种情况,这都不是一个合理的理由,去忽略对来源的过滤。

这不仅仅是 Zoom 的问题。根据我的经验,很多我交谈过的开发者对 CORS 的工作原理理解得并不好。在 Stack Overflow 上也有很多类似的例子。不幸的是,这些例子经常伴随着推荐非常不安全默认设置的页面,比如这个在 express 中的页面,如果直接复制使用,会使你的应用面临风险。其他厂商也曾被发现存在与 Zoom 相同的漏洞。

开发者只是希望他们的代码能正常运行,完全绕过同源策略可能会让代码运行起来,但一旦有人发现你这么做,你就会像 Zoom 现在一样遇到问题。

我看到无论是有经验还是刚入门的开发者,都会对 CORS 产生困惑。是 CORS API 太复杂、太令人困惑,还是我们只需要在 CORS 和 CSP 等问题上对开发者进行更好的教育?我不确定,但目前的做法显然没有奏效。

订阅电子邮件列表

©

Chris Foster

chris@fosterelli.co