JAVA WEB中处理防SQL注入|防XSS跨站脚本
在java web项目中,必然会涉及到从客户端向服务端提交数据,那么由于服务端对数据的处理等动作,会因为字符串拼接和使用的特殊性,存在一些漏洞被人利用。
这篇文章,主要介绍一下在java web项目中,程序设计上在什么位置进行集中处理,我想这一点还是比较重要的,我经常遇到一些新手也知道对提交数据进行处理,但是苦于不知道在什么位置处理,最终用了很low的方式,每次使用都处理一遍。
不多说话,直接上代码。
Servlet方式,通过Filter统一处理。
在java web项目中添加一个自定义的Filter类XSSFilter,用来拦截所有的请求,并对所有请求中的数据进行集中的处理。
注意:XssHttpServletRequestWrapper 这个自定义类的使用,下面会介绍这个类的用途。
import java.io.IOException;
import javax. servlet.Filter;
import javax. servlet.FilterChain;
import javax. servlet.FilterConfig;
import javax. servlet.ServletException;
import javax. servlet.ServletRequest;
import javax. servlet.ServletResponse;
import javax. servlet. http. HttpServletRequest;
publicclass XSSFilter implements Filter {
FilterConfig filterConfig = null;
publicvoid init (FilterConfig filterConfig) throws ServletException {
this. filterConfig = filterConfig;
}
publicvoid destroys () {
this. filterConfig = null;
}
publicvoid doFilter (ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain. doFilter (new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
}
}
很多新手而言集中处理所有请求,我想大家很容易想到通过Filter接口来处理,但是苦于Filter接口的doFilter(request, response, charn)中的request对象中的请求数据无何奈何,因为java.util.Map所包装的HttpServletRequest对象的参数是不可改变的。
但是java官方必然也会注意到这个问题,从而给出解决方案,所以HttpServletRequestWrapper工具类就出现了。
下面我们看一下官方对HttpServletRequestWrapper类的说明。
API 原文:
Provides a convenient implementation of the HttpServletRequest interface that can be subclassed by developers wishing to adapt the request to a Servlet.
This class implements the Wrapper or Decorator pattern. Methods default to calling through to the wrapped request object.
翻译:
提供一个方便,可以定义由开发人员要适应Servlet请求HttpServletRequest接口的实现。
该类实现了Wrapper接口。方法默认调用经过Wrapper包装的request对象。
import javax. servlet. http. HttpServletRequest;
import javax. servlet. http. HttpServletRequestWrapper;
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
public XssHttpServletRequestWrapper (HttpServletRequest servletRequest) {
super(servletRequest);
}
public String [] getParameterValues (String parameter) {
String [] values = super. getParameterValues(parameter);
if (values == null) {
return null;
}
int count = values. length;
String [] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = cleanXSS(values[i]);
}
return encodedValues;
}
public String getParameter (String parameter) {
String value = super. getParameter(parameter);
if (value == null) {
return null;
}
return cleanXSS(value);
}
public String getHeader (String name) {
String value = super. getHeader(name);
if (value == null)
return null;
return cleanXSS(value);
}
private String cleanXSS (String value) {
//建议下面片段使用StringBuffer对象处理。
value = value. replaceAll ("<", "& lt;"). replaceAll (">", "& gt;");
value = value. replaceAll ("\\ (", "& #40;"). replaceAll ("\\)", "& #41;");
value = value. replaceAll ("'", "& #39;");
value = value. replaceAll ("eval\\ ((. *)\\)", "");
value = value. replaceAll ("[\\\"\\\’] [\\s] *javascript:(. *)[\\\"\\\']", "\"\"");
value = value. replaceAll ("script", "");
return value;
}
}
最后不要忘记在配置中声明一下Filter
<filter>
<filter-name>XssSqlFilter</filter-name>
<filter-class>com.servlet.XSSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XssSqlFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
基于SpringMVC中的拦截器集中处理
在使用SpringMVC框架来说,集中处理一些事情还是比较容易的,Spring提供Interceptor机制,如果用的好的话,可以省去很多事情,不多说了,直接看代码吧。
import org.springframework.web. servlet.HandlerInterceptor;
import org.springframework.web. servlet.ModelAndView;
import javax. servlet. http. HttpServletRequest;
import javax. servlet. http. HttpServletResponse;
import java. util. Enumeration;
/**
* 防止SQL注入的拦截器
*/
publicclass SqlInjectInterceptor implements HandlerInterceptor {
publicboolean preHandle(HttpServletRequest request,HttpServletResponse response, Object o) throws Exception {
Enumeration names = request.getParameterNames ();
while (names. hasMoreElements()) {
String name = (String) names.nextElement();
String[] values = request.getParameterValues(name);
for (String value: values) {
value = clearXss(value);
}
}
returntrue;
}
publicvoid postHandle(HttpServletRequest request,HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {
}
publicvoidafterCompletion(HttpServletRequest request,HttpServletResponse response, Object o, Exception e)
throws Exception {
}
/**
* 处理字符转义
* @param value * @return
*/
private String clearXss (String value) {
if (value == null || "".equals(value)) {
returnvalue;
}
//建议下面片段使用StringBuffer对象处理。
value = value. replaceAll ("<", "<"). replaceAll (">", ">");
value = value.replaceAll("\\(", "(").replace("\\)", ")");
value = value. replaceAll ("'", "'");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replace("script", "");
returnvalue;
}
}