开发者对CORS的理解误区(2019)

Hacker News Top 新闻

摘要

本文解释了关于CORS的常见误解,并以Zoom漏洞为例,说明不当的CORS处理如何导致安全问题。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/06/21 04:30

# 开发者并不理解 CORS 来源:https://fosterelli.co/developers-dont-understand-cors ### 开发者并不理解 CORS 2019年7月10日 — Chris Foster 在全栈咨询工作中,最棒的一点就是我能与大量来自不同规模、不同行业的公司、拥有不同技能水平的开发者合作。这让我有机会观察哪些问题是普遍存在的。最近有一个常见且相关的问题:太多 Web 开发者并不理解 CORS 的工作原理。 指出这一点尤其及时,因为最近出现了 Zoom 漏洞(https://medium.com/bugbountywriteup/zoom-zero-day-4-million-webcams-maybe-an-rce-just-get-them-to-visit-your-website-ac75c83f4ef5)。安全研究员 Jonathan Leitschuh 发现 Zoom 在机器上监听了一个 Web 服务器,地址为 `http://localhost:19421`。当你加载一个 Zoom 链接时,Zoom 的网站会向这个本地 Web 服务器发送请求,并指示它打开原生的 Zoom 应用。整篇文章都值得一读,但以下部分让我印象深刻: > 我还发现,该页面并没有发出常规的 AJAX 请求,而是从本地运行的 Zoom Web 服务器加载了一张图片。图片的不同尺寸对应着服务器的错误/状态码。你可以在这里看到那个 case-switch 逻辑。我问的一个问题是:为什么这个 Web 服务器要把数据编码在图片文件的尺寸里?原因是,这样做是为了绕过跨域资源共享(CORS)。出于非常明确的原因,浏览器会显式地忽略针对 localhost 服务器的任何 CORS 策略。 最后一句话是不正确的——Chrome 确实尊重本地 Web 服务器的 CORS 头部(https://bugs.chromium.org/p/chromium/issues/detail?id=67743#c17)。如果你是一名 Web 开发者,你可能在同时使用 Create React App(前端应用在一个端口,后端 API 在另一个端口)时遇到过这种情况。你的应用在向 localhost 发出跨域请求,而所有浏览器都支持这一点。 在我看来,这说明 Zoom 可能需要尽快推出这个功能,但却不理解 CORS。他们无法在不被浏览器阻止的情况下发出 AJAX 请求。于是,他们构建了这种图片 hack 来 *绕过* CORS。这样一来,Zoom 就暴露在了严重的漏洞之下,因为不仅 Zoom 网站可以触发原生客户端中的操作并访问响应,互联网上的每个其他网站也都可以做到。 那么,这个功能的安全实现应该是什么样的?监听在 `localhost:19421` 的 Web 服务器应该实现一个 REST API,并在响应中设置 `Access-Control-Allow-Origin` 头部,值为 `https://zoom.us`。这将确保只有运行在 zoom.us 域上的 JavaScript 才能与本地 Web 服务器通信。此外,为了防止页面在后台自动打开 Zoom 会议,zoom.us 应该设置一个内容安全策略(CSP)头部(https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP),以阻止在 iframe 中渲染页面。 这仍然留有一个漏洞:任何页面都可以将你的浏览器重定向到一个你未预料到的 zoom.us 会议链接。但这是 Zoom 做出的用户体验决策,而非软件漏洞。就个人而言,我认为这种方法也有问题。他们提到希望通过直接打开应用来提供更好的用户体验,但良好用户体验设计的原则之一就是软件必须是可预测的。 如果我点击一个链接,我期望它不会突然让不认识我的人访问我的摄像头和麦克风。Zoom 打破了这种期望。即使他们出于用户体验原因不想使用内置的浏览器弹窗,也完全可以在应用内添加这个弹窗!Google Meet 在这方面做得很好: 我不想偏离本文关于 CORS 的核心。无论用户体验方面的争论如何,在 localhost 上运行一个 Web 服务器本身就是一个冒险的行为。它绝对不应该向互联网上的每个网站提供对功能(例如 *安装软件*)的特权访问。CORS 可以让你安全地做到这一点——不要绕过它! 我不能百分百确定是否因为不理解 CORS 才导致 Zoom 以这种方式实现该功能。然而,我与一些人讨论过,我们所有人都找不到任何合理的理由来实现他们现有的方法。在 Reddit 上,lerunicorn 发现并指出(https://www.reddit.com/r/programming/comments/cavblo/zoom_zero_day_4_million_webcams_maybe_an_rce_just/etdw0qn/)Firefox 可能会阻止从安全来源到非安全来源的 XHR,这或许可以解释这种实现背后的动机。但是,当来源是 localhost 时,Firefox 是支持 XHR 的。此外,原生应用可以生成唯一的自签名证书。或者,他们也可以使用浏览器扩展(https://palant.de/2019/04/11/bogus-security-mechanisms-encrypting-localhost-traffic/)。在任何可能的情况下,这都不是忘记过滤来源的有效理由。 不仅仅是 Zoom。根据我的经验,许多与我交谈过的开发者都不太理解 CORS 的工作原理。Stack Overflow 上也有大量相关示例(https://stackoverflow.com/search?q=Access-Control-Allow-Origin+node)。不幸的是,这些示例常常与推荐非常不安全默认设置的页面绑定在一起,比如这个(https://enable-cors.org/server_expressjs.html)Express 示例,如果直接复制粘贴,会让你的应用程序变得脆弱。其他厂商也曾被发现存在与 Zoom 完全相同的漏洞(https://bugs.chromium.org/p/project-zero/issues/detail?id=1663)。 开发者只想让代码跑起来,而完全绕过同源策略可能能让它暂时工作,但一旦有人发现你的做法,你就会面临像 Zoom 现在这样的问题。 我见过经验丰富和新手开发者对 CORS 的困惑。是 CORS API 太复杂难懂,还是我们只需要更好的开发者教育,比如围绕 CORS 和 CSP 这类问题?我不确定,但当前的方法显然不太奏效。

相似文章

CVE-2026-48710:维护者的视角

Lobsters Hottest

Marcelo Trylesinski 分享了他对 CVE-2026-48710 的看法,这是一个 Starlette 中的安全漏洞,涉及通过操纵 Host 标头绕过基于路径的授权。他认为该漏洞源于应用模式和部署方式,而非框架本身。

不要自己造轮子…

Lobsters Hottest

作者将“不要自己造轮子”的原则扩展到Web开发领域,反对自定义实现滚动、链接导航、文本选择等浏览器原生行为。

我们对 Axios 开发者工具安全事件的回应

OpenAI Blog

OpenAI 披露了一起安全事件,其中 Axios 开发者工具作为更广泛的供应链攻击的一部分被攻陷,可能导致其 macOS 代码签名证书泄露。OpenAI 未发现数据受损的证据,但正在主动撤销并轮换其证书,要求用户更新其 macOS 应用程序。

过时的CSS及其为何需要它

Lobsters Hottest

本文回顾了针对Internet Explorer版本的过时CSS技巧,如条件注释和解析器利用,突出了过去开发者如何应对浏览器不一致性。

React2Shell 的故事以及 Next.js 的后续发展

Lobsters Hottest

本文详细介绍了 CVE-2025-5518(React2Shell)的发现与披露过程。这是一个存在于 React Server Components 中的严重远程代码执行漏洞,研究人员通过绕过 Flight 协议的验证机制来访问对象原型。