XSS 攻击的防御

Posted 心若不动,风又奈何;你若不伤,岁月无恙。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XSS 攻击的防御相关的知识,希望对你有一定的参考价值。

  xss攻击预防,网上有很多介绍,发现很多都是只能预防GET方式请求的xss攻击,并不能预防POST方式的xss攻击。主要是由于POST方式的参数只能用流的方式读取,且只能读取一次,经过多次尝试,自己总结并经过多次尝试之后,终于成功了,废话不多说,上代码。

 

 

 

 

 

参考主要网址:

http://blog.csdn.net/Lan_Xuan/article/details/73826065

http://blog.csdn.net/happylee6688/article/details/40660797

http://www.cnblogs.com/digdeep/p/4695348.html

http://www.cnblogs.com/443855539-wind/p/6055816.html

http://blog.csdn.net/angevin/article/details/53992698

 

 

 

 

 

 

 

 

maven依赖:

       <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>javax.servlet-api</artifactId>
           <version>3.1.0</version>
           <scope>provided</scope>
       </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.0</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.spec.javax.servlet</groupId>
            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
            <version>1.0.0.Beta1</version>
        </dependency>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 web.xml

1     <filter>
2         <filter-name>XssEscape</filter-name>
3         <filter-class>com.*.webshell.XSSFilter</filter-class>
4     </filter>
5     <filter-mapping>
6         <filter-name>XssEscape</filter-name>
7         <url-pattern>/*</url-pattern>
8         <dispatcher>REQUEST</dispatcher>
9     </filter-mapping>

 

 XFFFilter.java

 1 import java.io.IOException;
 2 
 3 import javax.servlet.Filter;
 4 import javax.servlet.FilterChain;
 5 import javax.servlet.FilterConfig;
 6 import javax.servlet.ServletException;
 7 import javax.servlet.ServletRequest;
 8 import javax.servlet.ServletResponse;
 9 import javax.servlet.http.HttpServletRequest;
10 
11 public class XSSFilter implements Filter {
12 
13     FilterConfig filterConfig = null;
14 
15     public void init(FilterConfig filterConfig) throws ServletException {
16         this.filterConfig = filterConfig;
17     }
18 
19     public void destroy() {
20         this.filterConfig = null;
21     }
22 
23     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
24             throws IOException, ServletException {
25         chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
26     }
27 }

 

 

 

XssHttpServletRequestWrapper.java

  1 import java.io.BufferedReader;
  2 import java.io.ByteArrayInputStream;
  3 import java.io.IOException;
  4 import java.io.InputStreamReader;
  5 import java.io.UnsupportedEncodingException;
  6 import java.nio.charset.Charset;
  7 
  8 import javax.servlet.ReadListener;
  9 import javax.servlet.ServletInputStream;
 10 import javax.servlet.http.HttpServletRequest;
 11 import javax.servlet.http.HttpServletRequestWrapper;
 12 
 13 public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
 14     boolean isUpData = false;// 判断是否是上传 上传忽略
 15 
 16     public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {
 17         super(servletRequest);
 18         String contentType = servletRequest.getContentType();
 19         if (null != contentType)
 20             isUpData = contentType.startsWith("multipart");
 21     }
 22 
 23     @Override
 24     public String[] getParameterValues(String parameter) {
 25         String[] values = super.getParameterValues(parameter);
 26         if (values == null) {
 27             return null;
 28         }
 29         int count = values.length;
 30         String[] encodedValues = new String[count];
 31         for (int i = 0; i < count; i++) {
 32             encodedValues[i] = cleanXSS(values[i]);
 33         }
 34         return encodedValues;
 35     }
 36 
 37     @Override
 38     public String getParameter(String parameter) {
 39         String value = super.getParameter(parameter);
 40         if (value == null) {
 41             return null;
 42         }
 43         return cleanXSS(value);
 44     }
 45 
 46     /**
 47      * 获取request的属性时,做xss过滤
 48      */
 49     @Override
 50     public Object getAttribute(String name) {
 51         Object value = super.getAttribute(name);
 52         if (null != value && value instanceof String) {
 53             value = cleanXSS((String) value);
 54         }
 55         return value;
 56     }
 57 
 58     @Override
 59     public String getHeader(String name) {
 60 
 61         String value = super.getHeader(name);
 62         if (value == null)
 63             return null;
 64         return cleanXSS(value);
 65     }
 66 
 67     private static String cleanXSS(String value) {
 68         //几种常见的web攻击:http://jingyan.baidu.com/article/0202781178e19e1bcc9ce5c7.html
 69         value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
 70         //%3C是URL对<字符的编码
 71         value = value.replaceAll("%3C", "&lt;").replaceAll("%3E", "&gt;");
 72         value = value.replaceAll("\\\\(", "&#40;").replaceAll("\\\\)", "&#41;");
 73         //%28是(转义后的字符编码 , %29是)转义后的字符编码
 74         value = value.replaceAll("%28", "&#40;").replaceAll("%29", "&#41;");
 75         //&#39;是单引号ASCII编码后的表现形式
 76         value = value.replaceAll("\'", "&#39;");
 77         //eval() 函数可计算某个字符串,并执行其中的的 javascript 代码
 78         value = value.replaceAll("eval\\\\((.*)\\\\)", "");
 79         //防止如javascript:alert(doucment.cookie)可以看到当前站点的cookie(如果有的话)的攻击
 80         value = value.replaceAll("[\\\\\\"\\\\\\\'][\\\\s]*javascript:(.*)[\\\\\\"\\\\\\\']", "\\"\\"");
 81 //        value = value.replaceAll("script", "");
 82         return value;
 83     }
 84 
 85     @Override
 86     public ServletInputStream getInputStream() {
 87         try {
 88             if (isUpData) {
 89                 return super.getInputStream();
 90             } else {
 91 
 92                 final ByteArrayInputStream bais = new ByteArrayInputStream(
 93                         inputHandlers(super.getInputStream()).getBytes("utf-8"));
 94 
 95                 return new ServletInputStream() {
 96 
 97                     @Override
 98                     public int read() throws IOException {
 99                         return bais.read();
100                     }
101 
102                     @Override
103                     public boolean isFinished() {
104                         return false;
105                     }
106 
107                     @Override
108                     public boolean isReady() {
109                         return false;
110                     }
111 
112                     @Override
113                     public void setReadListener(ReadListener readListener) {
114                     }
115                 };
116             }
117         } catch (UnsupportedEncodingException e) {
118             e.printStackTrace();
119         } catch (IOException e) {
120             e.printStackTrace();
121         }
122         return null;
123 
124     }
125 
126     public String inputHandlers(ServletInputStream servletInputStream) {
127         StringBuilder sb = new StringBuilder();
128         BufferedReader reader = null;
129         try {
130             reader = new BufferedReader(new InputStreamReader(servletInputStream, Charset.forName("UTF-8")));
131             String line = "";
132             while ((line = reader.readLine()) != null) {
133                 sb.append(line);
134             }
135         } catch (IOException e) {
136             e.printStackTrace();
137         } finally {
138             if (servletInputStream != null) {
139                 try {
140                     servletInputStream.close();
141                 } catch (IOException e) {
142                     e.printStackTrace();
143                 }
144             }
145             if (reader != null) {
146                 try {
147                     reader.close();
148                 } catch (IOException e) {
149                     e.printStackTrace();
150                 }
151             }
152         }
153         return cleanXSS(sb.toString());
154     }
155 }

 

如果XssHttpServletRequestWrapper.java类中没有标红的那个代码会报如下错误,主要是因为过滤的参数中有中文

1 org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Invalid UTF-8 start byte 0xb1
2  at [Source: com.*.XssHttpServletRequestWrapper$1@6230dd4f; line: 1, column: 128] 
3  (through reference chain: com.*.entity.OrderTicket["address"]); 
4  nested exception is com.fasterxml.jackson.databind.JsonMappingException: Invalid UTF-8 start byte 0xb1
5  at [Source: com.*.XssHttpServletRequestWrapper$1@6230dd4f; line: 1, column: 128] 
6  (through reference chain: com.*.entity.*["address"])

 

以上是关于XSS 攻击的防御的主要内容,如果未能解决你的问题,请参考以下文章

XSS攻击的定义,类型以及防御方法?

XSS攻击及防御

XSS攻击及防御

6.XSS攻击方式及防御措施

前端 | XSS 的攻击方式及其防御

XSS攻击及防御