zoukankan      html  css  js  c++  java
  • 记一次JAVA WEB项目解决XSS攻击的办法(亲测有效)

    • 什么是XSS攻击

        简单来说,XSS 攻击是页面被注入了恶意的代码,度娘一大堆的东西,不想说

    • 系统架构主要是SSM框架,服务层另外使用了DubboX.

         为啥说这个,因为SpringMVC对于Xss攻击需要特殊处理

    • 思路  

        其实XSS工具解决思路就是捕获客户端提交的参数进行捕获,然后对参数值进行过滤处理,去除那些非法的字符.

        但是请求通常分为GET请求与POST请求,针对不同的请求,处理方式是不一样的

    • 步骤:

        1.针对GET与非文件格式上传的post请求.(form 表单提交的时候 没有这个参数enctype="multipart/form-data"),JSON请求等

    1) web.xml配置过滤器

     1 <!-- xxs过滤 --> 
     2 <filter> 
     3     <filter-name>XssSqlFilter</filter-name> 
     4     <filter-class>cn.ffcs.web.filter.XssFilter</filter-class> 
     5 </filter> 
     6 <filter-mapping> 
     7     <filter-name>XssSqlFilter</filter-name> 
     8     <url-pattern>/*</url-pattern> 
     9     <dispatcher>REQUEST</dispatcher> 
    10 </filter-mapping> 
    View Code

    2)过滤器实现 XssFilter.java,针对部分特殊请求,要求不走过滤的,可以在此过滤器中放行

     1 package cn.ffcs.web.filter;
     2 
     3 import java.io.IOException;
     4 
     5 import javax.servlet.FilterChain;
     6 import javax.servlet.ServletException;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 
    10 import org.slf4j.Logger;
    11 import org.slf4j.LoggerFactory;
    12 import org.springframework.web.filter.OncePerRequestFilter;
    13 
    14 public class XssFilter extends OncePerRequestFilter {
    15      private final Logger logger = LoggerFactory.getLogger(this.getClass());
    16      @Override
    17         protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
    18                 throws ServletException, IOException {
    19             try {
    20                 String uri = request.getRequestURI();
    21                 //特殊url不走过滤器
    22                 if (uri.contains("receipt") || uri.contains("mobile/buildingMgr")
    23                          || uri.contains("bestPay") || uri.contains("backNotify") || uri.contains("frontNotify")
    24                          || uri.contains("queryOrder") || uri.contains("refundNotify") || uri.contains("refund")
    25                          || uri.contains("reverse")) {
    26                     chain.doFilter(request, response);
    27                 } else {
    28                     XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
    29                     chain.doFilter(xssRequest, response);
    30                 }
    31             } catch (Exception e) {
    32                 logger.error("Xss过滤器,包装request对象失败");
    33                 chain.doFilter(request, response);
    34             }                
    35         }
    36 }
    View Code

    3) XssHttpServletRequestWrapper

      1 package cn.ffcs.web.filter;
      2 
      3 import javax.servlet.http.HttpServletRequest;
      4 import javax.servlet.http.HttpServletRequestWrapper;
      5 
      6 public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
      7 
      8     HttpServletRequest orgRequest = null;
      9      
     10     public XssHttpServletRequestWrapper(HttpServletRequest request) {
     11         super(request);
     12         orgRequest = request;
     13     }
     14  
     15     /**
     16      * 覆盖getParameter方法,将参数名和参数值都做xss过滤
     17      */
     18     @Override
     19     public String getParameter(String name) {
     20         String value = super.getParameter(xssEncode(name));
     21         if (value != null) {
     22             value = xssEncode(value);
     23         }
     24         return value;
     25     }
     26     /**
     27      * 覆盖getParameterValues方法,将参数名和参数值都做xss过滤
     28      */
     29     public String[] getParameterValues(String parameter) {
     30         String[] values = super.getParameterValues(parameter);
     31         if (values==null)  {
     32             return null;
     33         }
     34         int count = values.length;
     35         String[] encodedValues = new String[count];
     36         for (int i = 0; i < count; i++) {
     37             encodedValues[i] = xssEncode(values[i]);
     38         }
     39         return encodedValues;
     40     }
     41     
     42     /**
     43      * 获取request的属性时,做xss过滤
     44      */
     45      @Override
     46     public Object getAttribute(String name) {
     47         Object value = super.getAttribute(name);
     48         if (null != value && value instanceof String) {
     49             value = xssEncode((String) value);
     50         }
     51         return value;
     52     };
     53     
     54     /**
     55      * 覆盖getHeader方法,将参数名和参数值都做xss过滤。<br/>
     56      */
     57     @Override
     58     public String getHeader(String name) {
     59         String value = super.getHeader(xssEncode(name));
     60         if (value != null) {
     61             value = xssEncode(value);
     62         }
     63         return value;
     64     }
     65     
     66     
     67     /**
     68      * 将容易引起xss漏洞的半角字符直接替换成全角字符
     69      * 
     70      * @param s
     71      * @return
     72      */
     73     private static String xssEncode(String s) {
     74         return XssEncode.xssEncode(s);
     75     }
     76  
     77     /**
     78      * 获取最原始的request
     79      * 
     80      * @return
     81      */
     82     public HttpServletRequest getOrgRequest() {
     83         return orgRequest;
     84     }
     85  
     86     /**
     87      * 获取最原始的request的静态方法
     88      * 
     89      * @return
     90      */
     91     public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
     92         if (req instanceof XssHttpServletRequestWrapper) {
     93             return ((XssHttpServletRequestWrapper) req).getOrgRequest();
     94         }
     95  
     96         return req;
     97     }
     98     
     99 
    100 }
    View Code

    4) 使用到的编码工具,过滤参数使用了xss-html-filter工具,具体可以自行替换

     1 package cn.ffcs.web.filter;
     2 
     3 import net.sf.xsshtmlfilter.HTMLFilter;
     4 
     5 public class XssEncode {
     6     public static String xssEncode(String s) {
     7         if (s == null || s.isEmpty()) {
     8             return s;
     9         }
    10         try {
    11             HTMLFilter htmlFilter = new HTMLFilter();
    12             String clean = htmlFilter.filter(s);
    13             return clean;
    14         } catch (NullPointerException e) {
    15             return s;
    16         } catch (Exception ex) {
    17             ex.printStackTrace();
    18         }
    19  
    20         return null;
    21     }
    22 }
    View Code

    5) pom.xml 配置引用的jar

    1 <dependency>
    2        <groupId>net.sf.xss-html-filter</groupId>
    3        <artifactId>xss-html-filter</artifactId>
    4        <version>1.5</version> 
    5 </dependency>
    View Code

        2.针对enctype="multipart/form-data"格式的post提交

    1) 更改springMVC默认Annotation适配器(org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter - ->    cn.ffcs.web.filter.XssAnnotationMethodHandlerAdapter),如果没有则添加

    1 <!-- annotation方法修饰器 -->
    2 <bean id="handlerAdapter" class="cn.ffcs.web.filter.XssAnnotationMethodHandlerAdapter">
    3 
    4 ....
    5 
    6 <bean>

    2) 继承AnnotationMethodHandlerAdapter 并覆盖handle方法

     1 package cn.ffcs.web.filter;
     2 
     3 import java.util.Map;
     4 import java.util.Set;
     5 
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 
     9 import net.sf.xsshtmlfilter.HTMLFilter;
    10 
    11 import org.apache.commons.lang.StringUtils;
    12 import org.springframework.web.servlet.ModelAndView;
    13 import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
    14 @SuppressWarnings("deprecation")
    15 public class XssAnnotationMethodHandlerAdapter extends
    16         AnnotationMethodHandlerAdapter {
    17     
    18     
    19     @SuppressWarnings({ "rawtypes", "unchecked" })
    20     private void myXss(HttpServletRequest request){
    21         Map map = request.getParameterMap();
    22         Set<String> keySet = map.keySet();
    23         for(String key : keySet){
    24             String[] values = request.getParameterValues(key);
    25             if(values!=null&&values.length>0){
    26                 for(int i=0 ;i<values.length;i++){
    27                     if(!StringUtils.isBlank(values[i])){
    28                         values[i] = XssEncode.xssEncode(values[i]);
    29                     }
    30                 }
    31             }
    32         }
    33     }
    34     
    35     @Override
    36     public ModelAndView handle(HttpServletRequest request,
    37             HttpServletResponse response, Object handler) throws Exception {
    38         myXss(request);
    39         return super.handle(request, response, handler);
    40     }
    41 }
    View Code

    tip: 网上另外有说用反射实现带@Controller的控制器,感觉思路可以,但是没有成功.

  • 相关阅读:
    简简单单制作鼠标静态动态 ani cur 小结 鼠标形状指针
    【VB6 学习文档管理系统源码】
    Delphi 中的全局快捷键+给指定窗体发送按键
    C# 委托实例实现的多种类型
    PyCharm 上传项目到码云托管平台
    vs rdlc 设置Tablix 在新页面重复表头
    .net C# Chart控件的简单使用
    发邮件,阿里云,未指定邮件服务器端口导致的报错
    使用Quartz Job 简单的做一个定时服务
    FromBase64String 输入的不是有效的 Base-64 字符串,因为它包含非 Base-64 字符、两个以上的填充字符,或者填充字符间包含非法字符
  • 原文地址:https://www.cnblogs.com/zkongbai/p/10455783.html
Copyright © 2011-2022 走看看