Access-Control-Allow-Origin: null 的 Facebook Originull 漏洞是如何允许跨域访问的?

信息安全 网页浏览器 Facebook 同源策略 科尔斯 跨域
2021-08-30 09:31:21

最近,Facebook 的 Messenger 应用程序中的一个漏洞被修补和披露,该漏洞允许攻击者通过跨域 AJAX 访问用户的私人消息。

简单的错误允许黑客阅读您所有的私人 Facebook Messenger 聊天记录

此问题的根源在于 Facebook 聊天服务器域上的跨域标头实现配置错误,这使攻击者能够绕过源检查并从外部网站访问 Facebook 消息。

截屏

“Originull”的名称和屏幕截图似乎表明问题是以下标题:

Access-Control-Allow-Origin: null

但这让我想知道,值究竟是如何null导致漏洞的。这看起来不像是一个有效的来源,除非您以某种方式从域访问网站null(实际上,它需要是http://nullor https://null,因为需要包含协议)。

我检查过,null实际上并不是*Chrome 或 Firefox 中的允许值。

XMLHttpRequest 无法加载http://other.localhost/ajax.php“Access-Control-Allow-Origin”标头包含无效值“null”。因此,不允许访问源“ http://localhost ”。

*但是,使用 的值确实有效,因此显然仅仅存在null不足以让任意页面访问这些资源。)

浏览器中是否有一些读取null为 的功能或错误*或者浏览器中的某些功能,例如由数据 URI 打开的页面,允许匹配到null? 这个漏洞是如何工作的?

2个回答

我是 Ysrael,我是发现此漏洞的研究人员。

让我们把你的问题分成两部分: A. 浏览器的起源是怎么变成的nullB. nullOrigin如何影响 Facebook 服务器?

让我们从 A 开始。Origin 是 CORS 机制的一部分,它旨在告诉服务器请求来自哪里。当服务器收到请求时,服务器可以决定允许这个 Origin 接收响应。绕过此保护的方法之一是Open-Redirect在其中一个页面中找到一个,然后将用户定向到 dataURI 模式。过去,dataURI 收到了之前的 Origin,因为没有其他 Origin 可以给他。作为一项安全改进,现代浏览器将 Origin 设置为,null因此来自此 dataURI 页面的 XHR 请求将没有正确的 Origin。在 Chrome 中,无论如何都是这种情况,而在 Firefox 中,只有当页面通过元标记刷新到 dataURI 时才会发生这种情况。

于是,本源就变成了这样null

'Originull' 攻击使用此行为来绕过基于 Origin 的安全检查,因为大多数情况下,程序员不会将其null视为该字段中的值。

现在让我们进入 B 部分。这对 Facebook 有何影响。

FacebookAccess-Control-Allow-Origin在其 Messenger 服务器上使用,因为它们使用不同的子域。

最有可能的是,Messenger 子域在入口处有一个安全过滤器,然后将请求传递到响应用户的内部服务器。当服务器想要响应时,它从请求的 Origin 中获取值并将其返回到Access-Control-Allow-Originheader 中。这种开发设计允许 Facebook 仅在一个地方保持允许的 Origins。

messenger 子域也允许常规的 GET 请求。常规 GET 请求根本没有 Origin 标头。在许多开发语言中,不存在的 Header 返回 value null

因此,过滤器有一个允许null通过的条件(因此 GET 请求将正确通过),服务器获取它在请求的 Origin 标头 ( null) 中接收到的值,并将其在标头中返回给客户端Access-Control-Allow-Origin

很简单,对吧?;)

您可以在 BusSec 网站上的完整披露文档中找到技术细节和屏幕截图: https ://www.bugsec.com/wp-content/uploads/2016/12/Blog-Post-BugSec-Cynet-Facebook -Originull.pdf

这是可能的,Access-Control-Allow-Origin: null因为加载在数据 URI 和沙盒 iframe 等内容上的资源使用null源。记录该漏洞利用的 PDF 确认 Originull 使用数据 URI 文档来利用此标头来实现跨域访问

出于这个原因,W3C 建议避免为标头返回此值。

7.4. 避免返回Access-Control-Allow-Origin: "null"

return 似乎是安全的Access-Control-Allow-Origin: "null",但是使用非分层方案(例如data:or file:)和沙盒文档的任何资源的 Origin 的序列化被定义为“null”。许多用户代理将授予此类文档访问带有Access-Control-Allow-Origin: "null"标头的响应的权限,并且任何来源都可以创建具有“空”来源的恶意文档。因此应该避免 ACAO 标头的“null”值。

应用于“null”的 CORS 的简单字符串比较是有争议的。一些人认为“null”应该被视为表示缺少 Origin 的关键字标记,在测试时,不应将其与另一个“null”Origin 进行比较。null例如,SQL 中的值就是这种情况。)构建依赖“null”等于“null”比较的系统是不明智的,因为这种行为将来可能会改变。

事实证明,null当前的值没有什么特别的。它与 不一样*,它只是一个不那么特殊的来源,目前可以与无来源资源相匹配。

因此,如果您返回此标头(即使是偶然的):

Access-Control-Allow-Origin: null

您的资源目前可以跨域访问。