来源:https://www.cnblogs.com/insaneXs/p/7465014.html
XSS,全称为Cross Site Script,跨站脚本攻击,是WEB程序中一种常见的漏洞。其主要的攻击手段是在在利用网站上的可由用户输入信息的地方,恶意注入含有攻击性的脚本,达到攻击网站或者窃取用户cookied等隐私信息的目的。
XSS漏洞主要分为两种类型,一种是Stored XSS, 另一种是反射型 XSS。
第一种举个简单的例子就是BBS网站,黑客可以利用留言的功能,发表以下内容:
<script type="text/javascript"> alert("surprise") </script>
对系统而言,它认为这和其他的留言一样都只是字符串。但是当有用户访问到这个页面时,浏览器会把这段留言当成html内容来解析。因此就执行了其中的js脚本。
而反射型 XSS则是利用点击链接或是提交一些内容来达到攻击的目的。
比如我有以下一个页面:
<form name="formsearch" method="get">
<div class="form">
<input name="q" type="text" class="search-keyword" id="search-keyword" />
<button type="submit" class="search-submit blue-button">搜索</button>
</div>
</form>
当用户在input框中输入: "<script type="text/javascript"> alert(“surperise”) " 时。他也向浏览器插入了自己的JS脚本。
当表单被提交时,输入的字符串被作为参数放在了URL中,传到下一个页面。
当下一个页面需要显示这些内容,字符串中包含的攻击脚本也就被浏览器解释了出来。
当然这段脚本只能在自己的浏览器执行,可能没有什么攻击性,但是黑客们会想尽办法伪装页面达到攻击的目的。
总之,XSS攻击就是想办法让你的浏览器去执行他的脚本。
那么XSS攻击该如何预防呢?
既然是通过输入字符串达到植入脚本的目的,那么我们只要对用户输入的字符串进行一个html转义处理就好了。
我们可以利用org.apache.commons.lang3.StringEscapeUtils(注:3.6版本起,用commons-text包下的StringEscapeUtils代替)这个类对输入的参数进行html转义。
可以定义一个过滤器,然后转义HttpServletRequest中的参数值。
代码如下:
定义拦截器
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 @Override
13 public void init(FilterConfig filterConfig) throws ServletException {
14
15 }
16
17 @Override
18 public void doFilter(ServletRequest request, ServletResponse response,
19 FilterChain chain) throws IOException, ServletException {
20 chain.doFilter(new XSSHttpServletRequestWrapper((HttpServletRequest) request), response);
21 }
22
23 @Override
24 public void destroy() {
25
26 }
27
28
29 }
由于原生的HttpServletRequest不支持你直接修改参数,因此我们定义了一个包装类,在获取参数的时候对参数进行转义。
1 package com.jspxcms.core.support;
2
3 import javax.servlet.http.HttpServletRequest;
4 import javax.servlet.http.HttpServletRequestWrapper;
5
6 import org.apache.commons.lang3.StringEscapeUtils;
7
8 public class XSSHttpServletRequestWrapper extends HttpServletRequestWrapper {
9
10 public XSSHttpServletRequestWrapper(HttpServletRequest request) {
11 super(request);
12 }
13
14 @Override
15 public String getHeader(String name) {
16 return StringEscapeUtils.escapeHtml4(super.getHeader(name));
17 }
18
19 @Override
20 public String getQueryString() {
21 return StringEscapeUtils.escapeHtml4(super.getQueryString());
22 }
23
24 @Override
25 public String getParameter(String name) {
26 return StringEscapeUtils.escapeHtml4(super.getParameter(name));
27 }
28
29 @Override
30 public String[] getParameterValues(String name) {
31 String[] values = super.getParameterValues(name);
32 if(values != null) {
33 int length = values.length;
34 String[] escapseValues = new String[length];
35 for(int i = 0; i < length; i++){
36 escapseValues[i] = "1";
37 }
38 return escapseValues;
39 }
40 return super.getParameterValues(name);
41 }
42 }
最后我们在web.xml中配置我们的拦截器即可(将XXXX换成类的全限定名)。
1 <filter>
2 <filter-name>XssEscape</filter-name>
3 <filter-class>XXXXX.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>
简单的XSS防御就完成了。