首页 > 代码库 > XSS 攻击的防御

XSS 攻击的防御

  xss攻击预防,网上有很多介绍,发现很多都是只能预防GET方式请求的xss攻击,并不能预防POST方式的xss攻击。主要是由于POST方式的参数只能用流的方式读取,且只能读取一次,经过多次尝试,也只做到了能够接受GET、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

 

 

 

 

 

 

maven依赖:

       <!-- https://mvnrepository.com/artifact/antlr/antlr -->
        <dependency>
            <groupId>antlr</groupId>
            <artifactId>antlr</artifactId>
            <version>2.7.7</version>
        </dependency>
        
        <dependency>
            <groupId>org.antlr</groupId>
            <artifactId>antlr4-runtime</artifactId>
            <version>4.1</version>
        </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>

 

ThreadCache.java

 1 public class ThreadCache {
 2        // ThreadLocal里只存储了简单的String对象,也可以自己定义对象,存储更加复杂的参数
 3         private static ThreadLocal<String> threadLocal = new ThreadLocal<String>();
 4 
 5         public static String getPostRequestParams(){
 6             return threadLocal.get();
 7         }
 8         
 9         public static void setPostRequestParams(String postRequestParams){
10             threadLocal.set(postRequestParams);
11         }
12 
13         public static void removePostRequestParams(){
14             threadLocal.remove();
15         }
16     }

 

 

XSSFilter.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 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 
14 public class XSSFilter implements Filter {
15     private static Logger log = LoggerFactory.getLogger(XSSFilter.class);
16     
17     @Override
18     public void init(FilterConfig filterConfig) throws ServletException {
19     }
20 
21     @Override
22     public void destroy() {
23     }
24 
25     @Override
26     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
27             throws IOException, ServletException {
28            try {
29                 WrappedHttpServletRequest requestWrapper = new WrappedHttpServletRequest((HttpServletRequest) request);
30 
31                 if ("POST".equals(requestWrapper.getMethod().toUpperCase())) {
32                     // 获取请求参数
33                     String params = requestWrapper.getRequestParams();
34                     ThreadCache.setPostRequestParams(params);
35                     log.info("filer-post请求参数:[params={}]", params);
36                     System.out.println("filer-post请求参数:[params={}]"+ params);
37                 } else {
38                     log.info("非post请求");
39                 }
40 
41                 // 这里doFilter传入我们实现的子类
42                 chain.doFilter(requestWrapper, response);
43             } catch (Exception e) {
44                 log.error(e.getMessage(), e);
45             }
46     }
47 }

 

WrappedHttpServletRequest.java

  1 import org.apache.commons.io.IOUtils;
  2 
  3 import javax.servlet.ReadListener;
  4 import javax.servlet.ServletInputStream;
  5 import javax.servlet.http.HttpServletRequest;
  6 import javax.servlet.http.HttpServletRequestWrapper;
  7 import java.io.*;
  8 
  9 public class WrappedHttpServletRequest extends HttpServletRequestWrapper {
 10 
 11     private byte[] bytes;
 12     private WrappedServletInputStream wrappedServletInputStream;
 13 
 14     public WrappedHttpServletRequest(HttpServletRequest request) throws IOException {
 15         super(request);
 16         // 读取输入流里的请求参数,并保存到bytes里
 17         bytes = IOUtils.toByteArray(request.getInputStream());
 18         ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
 19         this.wrappedServletInputStream = new WrappedServletInputStream(byteArrayInputStream);
 20 
 21         // 很重要,把post参数重新写入请求流
 22         reWriteInputStream();
 23 
 24     }
 25 
 26     public String[] getParameterValues(String parameter) {
 27         String[] values = super.getParameterValues(parameter);
 28         if (values == null) {
 29             return null;
 30         }
 31         int count = values.length;
 32         String[] encodedValues = new String[count];
 33         for (int i = 0; i < count; i++) {
 34             encodedValues[i] = cleanXSS(values[i]);
 35         }
 36         return encodedValues;
 37     }
 38 
 39     public String getParameter(String parameter) {
 40 
 41         if ("POST".equals(super.getMethod().toUpperCase())) {
 42             String cleanXSS = cleanXSS(ThreadCache.getPostRequestParams());
 43             System.out.println("cleanXSS:" + cleanXSS);
 44             return cleanXSS;
 45         }
 46 
 47         String value = http://www.mamicode.com/super.getParameter(parameter);
 48         if (value =http://www.mamicode.com/= null) {
 49             return null;
 50         }
 51         return cleanXSS(value);
 52     }
 53 
 54     public String getHeader(String name) {
 55         String value = http://www.mamicode.com/super.getHeader(name);
 56         if (value =http://www.mamicode.com/= null)
 57             return null;
 58         return cleanXSS(value);
 59     }
 60 
 61     private String cleanXSS(String value) {
 62         value = http://www.mamicode.com/value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
 63         value = http://www.mamicode.com/value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
 64         value = http://www.mamicode.com/value.replaceAll("‘", "& #39;");
 65         value = http://www.mamicode.com/value.replaceAll("eval\\((.*)\\)", "");
 66         value = http://www.mamicode.com/value.replaceAll("[\\\"\\\‘][\\s]*javascript:(.*)[\\\"\\\‘]", "\"\"");
 67         value = http://www.mamicode.com/value.replaceAll("script", "");
 68         return value;
 69     }
 70 
 71     /**
 72      * 把参数重新写进请求里
 73      */
 74     public void reWriteInputStream() {
 75         wrappedServletInputStream.setStream(new ByteArrayInputStream(bytes != null ? bytes : new byte[0]));
 76     }
 77 
 78     @Override
 79     public ServletInputStream getInputStream() throws IOException {
 80         return wrappedServletInputStream;
 81     }
 82 
 83     @Override
 84     public BufferedReader getReader() throws IOException {
 85         return new BufferedReader(new InputStreamReader(wrappedServletInputStream));
 86     }
 87 
 88     /**
 89      * 获取post参数,可以自己再转为相应格式
 90      */
 91     public String getRequestParams() throws IOException {
 92         return new String(bytes, this.getCharacterEncoding());
 93     }
 94 
 95     private class WrappedServletInputStream extends ServletInputStream {
 96 
 97         public void setStream(InputStream stream) {
 98             this.stream = stream;
 99         }
100 
101         private InputStream stream;
102 
103         public WrappedServletInputStream(InputStream stream) {
104             this.stream = stream;
105         }
106 
107         @Override
108         public int read() throws IOException {
109             return stream.read();
110         }
111 
112         @Override
113         public boolean isFinished() {
114             return true;
115         }
116 
117         @Override
118         public boolean isReady() {
119             return true;
120         }
121 
122         @Override
123         public void setReadListener(ReadListener readListener) {
124 
125         }
126     }
127 }

 

XSS 攻击的防御