开发者不了解 CORS(2019)

2026-06-21 1 阅读 toilet
Chris Foster 博客> - 简介 - 会谈 开发人员不了解 CORS 2019 年 7 月 10 日 — Chris Foster 在全栈咨询工作中最好的事情之一是,我可以与来自不同规模和行业的公司中具有不同技能水平的大量开发人员合作。这提供了一个机会来了解普遍的斗争会发生什么。最近似乎常见且相关的一个问题是:太多的 Web 开发人员不了解 CORS 的工作原理。由于最近出现了 Zoom 漏洞,这一点显得特别及时。安全研究员 Jonathan Leitschuh 发现 Zoom 有一个 Web 服务器在 http://localhost:19421 上监听机器。当您加载 Zoom 链接时,Zoom 的网站会向本地主机网络服务器发送请求,并告诉它打开本机 Zoom 应用程序。整篇文章值得一读,但这些部分让我印象深刻:我还发现,该页面不是发出常规 AJAX 请求,而是从本地运行的 Zoom Web 服务器加载图像。图像的不同尺寸决定了服务器的错误/状态代码。您可以在这里看到大小写切换逻辑。我问的一个问题是,为什么这个网络服务器返回以图像文件的尺寸编码的数据?原因是,这样做是为了绕过跨源资源共享(CORS)。出于非常有意的原因,浏览器明确忽略本地主机上运行的服务器的任何 CORS 策略。最后一句话是不正确的——Chrome 确实尊重本地主机网络服务器的 CORS 标头。如果您是一名 Web 开发人员,当您使用一个端口上的前端应用程序和另一个端口上的后端 API 创建 React App 时,您可能已经完成了此操作。您的应用程序正在针对本地主机发出跨源请求,并且所有浏览器都支持这一点。这对我来说意味着 Zoom 可能需要推出这个功能并且不理解 CORS。如果浏览器不允许尝试,他们就无法发出 AJAX 请求。相反,他们构建了这个图像 hack 来解决 CORS。通过这样做,他们给 Zoom 带来了一个大漏洞,因为 Zoom 网站不仅可以在本机客户端中触发操作并访问响应,而且互联网上的所有其他网站也可以。那么这个功能的安全实现会是什么样子呢?监听 localhost:19421 的网络服务器应实现 REST API 并设置 Access-Control-Allow-Origin 标头,其值为 https://zoom.us 。这将确保只有在 Zoom.us 域上运行的 Javascript 才能与本地主机网络服务器通信。此外,为了阻止页面在后台自动打开 Zoom 会议,zoom.us 应该有一个内容安全策略标头来阻止 iframe 内的渲染。这仍然留下了一个漏洞,即任何页面都可以将您的浏览器重定向到您意想不到的会议的 Zoom.us 链接,但这是 Zoom 做出的用户体验决定,而不是软件漏洞。就我个人而言,我认为这里的方法也是错误的。他们提到,他们希望通过直接打开应用程序获得更好的用户体验,但良好的用户体验设计的规则之一是您的软件必须是可预测的。如果我点击一个链接,我希望它不会突然让我不认识的人可以使用我的相机和麦克风。 Zoom 打破了这一预期。即使他们出于用户体验原因不想要内置浏览器弹出窗口,也可以将此弹出窗口放在应用程序中! Google Meet 在这方面做得很好:我不想脱离这篇文章的 CORS 重点。无论争论的用户体验如何,在本地主机上运行网络服务器一开始就是一项冒险的尝试。它绝对不应该向互联网上的每个网站提供对功能的特权访问,例如安装软件。 CORS 使您能够安全地执行此操作 – 不要绕过它!我不确定 Zoom 以这种方式实现该功能是否是因为不理解 CORS。然而,我和一些人交谈过,我们中没有人能够共同找到任何合理的理由来实施他们现有的方法。在 reddit 上,lerunicorn 确实发现并建议 Firefox 可能会阻止 XHR 从安全来源到非安全来源,这可以解释这种方法背后的动机。但是,当源是 localhost 时,Firefox 支持此功能。此外,本机应用程序可以生成唯一的自签名证书。或者,他们可以使用浏览器扩展。在任何可能的情况下,这都不是忘记过滤来源的正当理由。这不仅仅是 Zoom。有趣的是,我采访过的许多开发人员都不太了解 CORS 的工作原理。 Stack Overflow 上的问题也提供了大量示例。不幸的是,这些通常与推荐非常不安全的默认值的页面配对,例如 Express 中的这个默认值,如果逐字复制,将使您的应用程序容易受到攻击。其他供应商也发现了 Zoom 中发现的完全相同的漏洞。开发者只是想获得