防止js注入

有的时候页面中会有一个输入框,用户输入内容后会显示在页面中,类似于网页聊天应用。如果用户输入了一段js脚本,比例:<script>alert('test');</script>,页面会弹出一个对话框,或者输入的脚本中有改变页面js变量的代码则会时程序异常或者达到跳过某种验证的目的。那如何防止这种恶意的js脚本攻击呢?

​​使用HttpServletRequestWrapper重写Request请求参数​​

目的: 改变请求参数的值,满足项目需求(如:过滤请求中 lang != zh 的请求)

方法: 1.使用 HttpServletRequestWrapper重写

1 public class ChangeRequestWrapper extends HttpServletRequestWrapper {
2 private Map<String, String[]> parameterMap; // 所有参数的Map集合
3
4 public ChangeRequestWrapper(HttpServletRequest request) {
5 super(request);
6 parameterMap = request.getParameterMap();
7 }
8
9 // 重写几个HttpServletRequestWrapper中的方法
10
11 /**
12 * 获取所有参数名
13 *
14 * @return 返回所有参数名
15 */
16 @Override
17 public Enumeration<String> getParameterNames() {
18 Vector<String> vector = new Vector<String>(parameterMap.keySet());
19 return vector.elements();
20 }
21
22 /**
23 * 获取指定参数名的值,如果有重复的参数名,则返回第一个的值 接收一般变量 ,如text类型
24 *
25 * @param name 指定参数名
26 * @return 指定参数名的值
27 */
28 @Override
29 public String getParameter(String name) {
30 String[] results = parameterMap.get(name);
31 return results[0];
32 }
33
34
35 /**
36 * 获取指定参数名的所有值的数组,如:checkbox的所有数据
37 * 接收数组变量 ,如checkobx类型
38 */
39 @Override
40 public String[] getParameterValues(String name) {
41 return parameterMap.get(name);
42 }
43
44 @Override
45 public Map<String, String[]> getParameterMap() {
46 return parameterMap;
47 }
48
49 public void setParameterMap(Map<String, String[]> parameterMap) {
50 this.parameterMap = parameterMap;
51 }
52 }

防止js注入

import org.springframework.web.util.HtmlUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}

@Override
public String getHeader(String name) {
String value = super.getHeader(name);
return HtmlUtils.htmlEscape(value);
}

@Override
public String getParameter(String name) {
String value = super.getParameter(name);
return HtmlUtils.htmlEscape(value);
}

@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values != null) {
int length = values.length;
String[] escapseValues = new String[length];
for (int i = 0; i < length; i++) {
escapseValues[i] = HtmlUtils.htmlEscape(values[i]);
}
return escapseValues;
}
return super.getParameterValues(name);
}


}

方法二、新增Filter

public class LangFilter implements Filter {
2 @Override
3 public void init(FilterConfig filterConfig) throws ServletException {
4
5 }
6
7 @Override
8 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
9
10 ChangeRequestWrapper changeRequestWrapper = new ChangeRequestWrapper((HttpServletRequest) servletRequest);
11
12 Map<String, String[]> parameterMap = new HashMap<>(changeRequestWrapper.getParameterMap());
13
14 String[] strings = parameterMap.get("lang");
//逻辑代码给定默认的参数值,如果参数不为中文,则直接返回异常
15 if (strings == null || strings.length == 0) {
16 strings = new String[1];
17 strings[0] = "zh";
18 parameterMap.put("lang", strings);
19 changeRequestWrapper.setParameterMap(parameterMap);
20 }else{
21 String language = strings[0];
22 if (!language.equals("zh")) {
23 Map<String,String> error = new HashMap<>();
24 error.put("code","500");
25
26 ServletOutputStream outputStream = null;
27 try {
28 outputStream = servletResponse.getOutputStream();
29 outputStream.write(JSONUtils.obj2Byte(error));
30 } finally {
31 if (outputStream != null) {
32 outputStream.flush();
33 outputStream.close();
34 }
35 }
36
37 return;
38 }
39 }
40 //使用复写后的wrapper
41 filterChain.doFilter(changeRequestWrapper, servletResponse);
42 }
43
44 @Override
45 public void destroy() {
46
47 }
48 }

web.xml增加一个过滤器处理

1   <filter>
2 <filter-name>languageFilter</filter-name>
3 <filter-class>com.intercepor.LangFilter</filter-class>
4 <init-param>
5 <param-name>encoding</param-name>
6 <param-value>UTF-8</param-value>
7 </init-param>
8 <init-param>
9 <param-name>forceEncoding</param-name>
10 <param-value>true</param-value>
11 </init-param>
12 </filter>
13
14 <filter-mapping>
15 <filter-name>languageFilter</filter-name>
16 <url-pattern>*.do</url-pattern>
17 </filter-mapping>

所有.do的请求,都会验证此参数