最近,经过测试,我发现在Facebook中存在一个新漏洞。利用该漏洞,我能够向任何带有CSRF(Cross-site request forgery,跨站请求伪造)防御的Facebook端点,或其外部主机,发送一个POST请求,并且能够得到响应。也即是说,我能够再一次绕过Facebook CSRF。
这个漏洞和我在2015年发现的那个,有着相似之处:能让攻击者绕过CSRF。以HTTP Request中的Body为例,如果想要网站响应类似于Request Body:fb_dtsg等,带有绕过CSRF防御标识的请求,那么就必须在服务器端进行验证。而如果一个请求不带有该标识,Facebook则不会实现其代码要求的任何功能。
与此同时,我在Facebook Lead Ads(Facebook公司推出的一个市场商务API,能够帮助用户快速地浏览其所需要的商业信息)工具中的Continued Flow模块里,又发现了另一个漏洞。
Continued Flow模块的功能是在广告商的网站上,帮助用户完成对商业信息的筛选,也是整个过程的最后一步。Lead Ads会收集所有的数据,并将其发送到一个使用Hash或POST请求的目标URL上。Continued Flow会保留一些你所需要,而Facebook本身不会存储的数据流。比如:在创建用户时设定的密码以及其他信息。
在Facebook的Continued Flow模块以及其他一些加入了fb_dtsg请求的模块中,都有实现POST请求的方法。
根据前文的介绍,我们需要创建一个Continued Flow Lead Ad类,来研究其中存在的漏洞;同时,根据有关文档的说明,该模块的使用权限仅仅属于白名单上的用户。未经授权的用户无法使用。但是,我用了一个小“技巧”,就绕过了这一限制。
只要用户创建了一个lead ad类型的集合,同时就会产生一个包含有相关数据的JSON(JavaScript Object Notation,JavaScript对象表示法)对象。它会将数据用于创建新的端口节点。幸运的是,我找到了另一个端点,它具有与JSON类型端点同样的功能,并且我还找到了一些关键代码:
我将上述代码、修改过的参数,以及Continued Flow集合创建过程的代码,一起添加到了JSON中的formbuilder项目里。在此过程中,并未进行任何的端口验证。
下面的链接和代码是对如何禁用时间轴审核的具体介绍:
Endpoint URL: https://facebook.com/ajax/settings/timeline/review.php
Body: tag_approval_enabled=0
FinalURL: https://facebook.com/ajax/settings/timeline/review.php?tag_approval_enabled=0&__a=1
最后,我用Facebook Tools对其进行了测试。很幸运,我成功了,再一次地绕过了CSRF。
在此过程中还有个小花絮:
如果我们将自定义字段的名字设置为fb_dtsg,有趣的一幕出现了:
名字设置的冲突,使得fb_dtsg的情况介绍出现了乱码。
https://www.facebook.com/DynamicW0rld/videos/262843317399202/,在此链接中,有介绍作者这一测试过程的视频。
时间轴:
2016.3.29:发现漏洞;
2016.4.06:请求更多情况介绍,并得到回复;
2016.4.07:Facebook安全人员证实bug存在;
测试过程中发现存在花絮;
2016.4.12:bug修复;
2016.4.13:Facebook奖励我7500美元;
2016.4.18:白名单信息完善;
2016.5.06:第二个bug修复;