java 防止 XSS 攻击的常用方法总结.

标签: java xss 攻击 | 发表时间:2016-03-19 09:33 | 作者:aoyouzi
出处:http://www.iteye.com

 

java web应用程序防止 csrf 攻击的方法,参考这里  java网页程序采用 spring 防止 csrf 攻击. ,但这只是攻击的一种方式,还有其他方式,比如今天要记录的 XSS 攻击, XSS 攻击的专业解释,可以在网上搜索一下,参考百度百科的解释  http://baike.baidu.com/view/2161269.htm, 但在实际的应用中如何去防止这种攻击呢,下面给出几种办法.
1. 自己写 filter 拦截来实现,但要注意的时,在WEB.XML 中配置 filter 的时候,请将这个 filter 放在第一位.
2. 采用开源的实现 ESAPI library ,参考网址: https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API

3. 可以采用spring 里面提供的工具类来实现.

一, 第一种方法。
配置过滤器

publicclassXSSFilterimplementsFilter{
    @Override
    publicvoid init(FilterConfig filterConfig)throwsServletException{
    }
    @Override
    publicvoid destroy(){
    }
    @Override
    publicvoid doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
        throwsIOException,ServletException{
        chain.doFilter(newXSSRequestWrapper((HttpServletRequest) request), response);
    }}



再实现 ServletRequest 的包装类

import java.util.regex.Pattern;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;publicclassXSSRequestWrapperextendsHttpServletRequestWrapper{
    publicXSSRequestWrapper(HttpServletRequest servletRequest){
        super(servletRequest);
    }
    @Override
    publicString[] getParameterValues(String parameter){
        String[] values =super.getParameterValues(parameter);
        if(values ==null){
            returnnull;
        }
        int count = values.length;
        String[] encodedValues =newString[count];
        for(int i =0; i < count; i++){
            encodedValues[i]= stripXSS(values[i]);
        }
        return encodedValues;
    }
    @Override
    publicString getParameter(String parameter){
        String value =super.getParameter(parameter);
        return stripXSS(value);
    }
    @Override
    publicString getHeader(String name){
        String value =super.getHeader(name);
        return stripXSS(value);
    }
    privateString stripXSS(String value){
        if(value !=null){
            // NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
            // avoid encoded attacks.
            // value = ESAPI.encoder().canonicalize(value);
            // Avoid null characters
            value = value.replaceAll("","");
            // Avoid anything between script tags
            Pattern scriptPattern =Pattern.compile("(.*?)",Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid anything in a src="http://www.yihaomen.com/article/java/..." type of e­xpression
            scriptPattern =Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",Pattern.CASE_INSENSITIVE |Pattern.MULTILINE |Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            scriptPattern =Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"",Pattern.CASE_INSENSITIVE |Pattern.MULTILINE |Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome  tag
            scriptPattern =Pattern.compile("",Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome  tag
            scriptPattern =Pattern.compile("",Pattern.CASE_INSENSITIVE |Pattern.MULTILINE |Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid eval(...) e­xpressions
            scriptPattern =Pattern.compile("eval\\((.*?)\\)",Pattern.CASE_INSENSITIVE |Pattern.MULTILINE |Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid e­xpression(...) e­xpressions
            scriptPattern =Pattern.compile("e­xpression\\((.*?)\\)",Pattern.CASE_INSENSITIVE |Pattern.MULTILINE |Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid javascript:... e­xpressions
            scriptPattern =Pattern.compile("javascript:",Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid vbscript:... e­xpressions
            scriptPattern =Pattern.compile("vbscript:",Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid onload= e­xpressions
            scriptPattern =Pattern.compile("onload(.*?)=",Pattern.CASE_INSENSITIVE |Pattern.MULTILINE |Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
        }
        return value;
    }}



例子中注释的部分,就是采用 ESAPI library 来防止XSS攻击的,推荐使用.

当然,我还看到这样一种办法,将所有的编程全角字符的解决方式,但个人觉得并没有上面这种用正则表达式替换的好

privatestaticString xssEncode(String s){
        if(s ==null|| s.equals("")){
            return s;
        }
        StringBuilder sb =newStringBuilder(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('\\');
                sb.append('\'');
                sb.append('\\');
                sb.append('\'');
                break;
            case'\"':
                sb.append('\\');
                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();
    }



当然,还有如下更简单的方式:

privateString cleanXSS(String value){
                //You'll need to remove the spaces from the html entities below
        value = value.replaceAll("<","& lt;").replaceAll(">","& gt;");
        value = value.replaceAll("\\(","& #40;").replaceAll("\\)","& #41;");
        value = value.replaceAll("'","& #39;");
        value = value.replaceAll("eval\\((.*)\\)","");
        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']","\"\"");
        value = value.replaceAll("script","");
        return value;
    }



在后台或者用spring 如何实现呢:
首先添加一个jar包:commons-lang-2.5.jar ,然后在后台调用这些函数:

StringEscapeUtils.escapeHtml(string);StringEscapeUtils.escapeJavaScript(string);StringEscapeUtils.escapeSql(string);



当然,我记得在spring 里面好像有一个 HtmlUtils.htmlEscape , 同样可以做到 过滤 XSS 攻击。从上面的介绍可以看出,防止 XSS 攻击并不难,就是要小心。

===============================================================

在apache commons-lang(2.3以上版本)中为我们提供了一个方便做转义的 工具类,主要是为了防止sql注入,xss注入攻击的功能。总共提供了以下几个方法:

 

1.escapeSql 提供sql转移功能,防止sql注入攻击,例如典型的万能密码攻击' ' or 1=1 ' '

  1. StringBuffer sql = new StringBuffer("select key_sn,remark,create_date from tb_selogon_key where 1=1 ");  
  2.         if(!CommUtil.isEmpty(keyWord)){  
  3.             sql.append(" and like '%" + StringEscapeUtils.escapeSql(keyWord) + "%'");  
  4.         }  
StringBuffer sql = new StringBuffer("select key_sn,remark,create_date from tb_selogon_key where 1=1 ");
		if(!CommUtil.isEmpty(keyWord)){
			sql.append(" and like '%" + StringEscapeUtils.escapeSql(keyWord) + "%'");
		}

2.escapeHtml /unescapeHtml  转义/反转义html脚本

  1. System.out.println(StringEscapeUtils.escapeHtml("<a>dddd</a>"));     
  2. 输出结果为:&lt;a&gt;dddd&lt;/a&gt;  
System.out.println(StringEscapeUtils.escapeHtml("<a>dddd</a>"));   
输出结果为:&lt;a&gt;dddd&lt;/a&gt;
  1. System.out.println(StringEscapeUtils.unescapeHtml("&lt;a&gt;dddd&lt;/a&gt;"));     
  2. 输出为:<a>ddd</a>  
System.out.println(StringEscapeUtils.unescapeHtml("&lt;a&gt;dddd&lt;/a&gt;"));   
输出为:<a>ddd</a>

3.escapeJavascript/unescapeJavascript 转义/反转义js脚本

  1. System.out.println(StringEscapeUtils.escapeJavaScript("<script>alert('1111')</script>"));     
  2. 输出为:&lt;script&gt;alert('111')&lt;/script&gt;  
System.out.println(StringEscapeUtils.escapeJavaScript("<script>alert('1111')</script>"));   
输出为:&lt;script&gt;alert('111')&lt;/script&gt;

4.escapeJava/unescapeJava 把字符串转为unicode编码

  1. System.out.println(StringEscapeUtils.escapeJava("中国"));     
  2. 输出为:用escapeJava方法转义之后的字符串为:/u4E2D/u56FD/u5171/u4EA7/u515A  

==============================================

  apache工具包common-lang中有一个很有用的处理字符串的工具类,其中之一就是StringEscapeUtils,这个工具类是在2.3版本以上加上的去的,利用它能很方便的进行html,xml,java等的转义与反转义,而且还能对关键字符串进行处理预防SQL注入,不过好像common-lang3.0以后我看着好像没这个处理SQL语句的方法了,想用的话前提时引入对应的jar包,以下为它的部分方法:

它的方法,全是静态,直接用类调用即可,下边来根据代码看看它们几个的用法和效果,一看一目了然:

 

[java]  view plain  copy
 
  1. package stringescapeutils;  
  2.   
  3. import org.apache.commons.lang.StringEscapeUtils;  
  4.   
  5. public class StringEscapeUtilsTest {  
  6.   
  7.     public static void main(String args[]){  
  8.           
  9.         String sql="1' or '1'='1";  
  10.         System.out.println("防SQL注入:"+StringEscapeUtils.escapeSql(sql)); //防SQL注入  
  11.           
  12.         System.out.println("转义HTML,注意汉字:"+StringEscapeUtils.escapeHtml("<font>chen磊  xing</font>"));    //转义HTML,注意汉字  
  13.         System.out.println("反转义HTML:"+StringEscapeUtils.unescapeHtml("<font>chen磊  xing</font>"));  //反转义HTML  
  14.           
  15.         System.out.println("转成Unicode编码:"+StringEscapeUtils.escapeJava("陈磊兴"));     //转义成Unicode编码  
  16.           
  17.         System.out.println("转义XML:"+StringEscapeUtils.escapeXml("<name>陈磊兴</name>"));   //转义xml  
  18.         System.out.println("反转义XML:"+StringEscapeUtils.unescapeXml("<name>陈磊兴</name>"));    //转义xml  
  19.           
  20.     }  
  21. }  

 

 

 

 

输入结果:

 

 

[java]  view plain  copy
 
  1. 防SQL注入:1'' or ''1''=''1  
  2. 转义HTML,注意汉字:<font>chen磊  xing</font>  
  3. 反转义HTML:<font>chen磊  xing</font>  
  4. 转成Unicode编码:\u9648\u78CA\u5174  
  5. 转义XML:<name>陈磊兴</name>  
  6. 反转义XML:<name>陈磊兴</name>  

 

http://blog.csdn.net/chenleixing/article/details/43456987

http://www.cnblogs.com/thinkpad/p/4837841.html

http://blog.csdn.net/joeyon1985/article/details/43527987



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [java xss 攻击] 推荐:

java 防止 XSS 攻击的常用方法总结.

- - 行业应用 - ITeye博客
自己写 filter 拦截来实现,但要注意的时,在WEB.XML 中配置 filter 的时候,请将这个 filter 放在第一位. 采用开源的实现 ESAPI library ,参考网址: https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API.

前端xss攻击

- - SegmentFault 最新的文章
实习的时候在项目中有接触过关于xss攻击的内容,并且使用了项目组中推荐的一些常用的防xss攻击的方法对项目进行了防攻击的完善. 但一直没有时间深入了解这东西,在此,做一个简单的梳理. xss跨站脚本攻击(Cross Site Scripting),是一种经常出现在web应用中的计算机安全漏洞,它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入的恶意html代码会被执行,从而达到恶意用户的特殊目的.

XSS攻击及防御

- - BlogJava-qileilove
XSS又称CSS,全称Cross SiteScript,跨站脚本攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式,所以容易被忽略其危害性. 其原理是攻击者向有XSS漏洞的网站中输入(传入)恶意的HTML代码,当其它用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的.

XSS攻击技术详解

- - BlogJava-qileilove
  XSS攻击:跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆. web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中. 比如这些代码包括HTML代码和客户端脚本. 攻击者利用XSS漏洞旁路掉访问控制--例如同源策略(same origin policy).

XSS攻击及防御

- - 互联网 - ITeye博客
       本文来自: 高爽|Coder,原文地址: http://blog.csdn.net/ghsau/article/details/17027893,转载请注明.         XSS又称CSS,全称Cross SiteScript,跨站脚本攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式,所以容易被忽略其危害性.

新浪微博的XSS攻击

- 铭文 - 酷壳 - CoolShell.cn
今天晚上(2011年6月28日),新浪微博出现了一次比较大的XSS攻击事件. 大量用户自动发送诸如:“郭美美事件的一些未注意到的细节”,“建党大业中穿帮的地方”,“让女人心动的100句诗歌”,“3D肉团团高清普通话版种子”,“这是传说中的神仙眷侣啊”,“惊爆!范冰冰艳照真流出了”等等微博和私信,并自动关注一位名为hellosamy的用户.

【原创】腾讯微博的XSS攻击漏洞

- sec314 - 博客园-首页原创精华区
相信大家都知道新浪微博在6月28日发生的XSS攻击事件了吧. 在那晚里,大量新浪微博用户自动发送微博信息和自动关注一名叫“hellosamy“的用户. 究竟XSS攻击为什么能有这么大的威力. 现在很多网站都采用了Cookie记录访问者的登录状态,在进行某些功能操作时(比如:发微博),服务器判断用户的Cookie记录的登录状态,如果用户是登录状态的则允许操作.

使用Http-only Cookie来防止XSS攻击

- - 标点符
www服务依赖于Http协议实现,Http是无状态的协议,所以为了在各个会话之间传递信息,就不可避免地用到Cookie来标记访问者的状态. 只要获得这个Cookie,就可以取得别人的身份,入侵个人账户或者网站. 对于网站来说,一旦存在了xss漏洞就意味着入侵者可以在浏览器中执行任意的JS脚本,这时候获得Cookie就变得非常的简单.

基于Antisamy项目实现防XSS攻击

- - CSDN博客互联网推荐文章
    最近项目上线,请第三方公司进行了一次渗透性测试,被发现存在多处XSS攻击. 由于我们对于URL的Get请求已经通过URLFilter进行了特殊字符过滤,Get请求的漏洞已经被封堵,但是对于Post请求考虑到我们项目存在表单提交,富文本编辑等功能,不敢贸然的使用Filter对关键字进行过滤. 为了解决上述问题,我们采用了OWASP的一个开源的项目AntiSamy来彻底解决XSS攻击问题.

网站攻防之CSRF和XSS跨站脚本攻击

- - CSDN博客推荐文章
进入正题之前,先扯一番:黑客本义并非某些人以为的利用网络干坏事的人,刚开始或者说现在的很多,黑客是以技术大牛的形式存在的,也就是在网络领域有一门专场的牛人. 有些黑客不干坏事而是干好事,比如利用网站的漏洞,去告诉网站开发运营者你的网站有漏洞,要修补啦,他们却并不会利用这漏洞干坏事,而是以发现漏洞追求技术快感为享受.