本文介绍解决Xss跨站脚本漏洞的方法,本方法解决思路为对request请求进行包装,重写request相关方法,对参数进行转义及过滤。注意此方案只适用于通过request获取普通参数,对于传输的json方式的参数无效,如需解决json方式参数,需要在json序列化或者反序列化时对内容进行转义,解决思路一致。
需要的类主要包括:
- XssFiter.java
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;
public class XssFiter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
XssAndHttpServletRequestWrapper xssRequestWrapper = new XssAndHttpServletRequestWrapper(req);
chain.doFilter(xssRequestWrapper, response);
}
public void destroy() {
}
}
- XssAndHttpServletRequestWrapper
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class XssAndHttpServletRequestWrapper extends HttpServletRequestWrapper {
HttpServletRequest request;
public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
// System.out.println("name:" + name + "," + value);
if (value != null) {
// 转换Html
value = XssUtil.cleanXss(value);
}
return value;
}
@Override
public String getHeader(String name) {
return XssUtil.cleanXss(super.getHeader(name));
}
@Override
public String getQueryString() {
return XssUtil.cleanXss(super.getQueryString());
}
@Override
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] = XssUtil.cleanXss(values[i]);
}
return encodedValues;
}
}
- XssUtil.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class XssUtil {
private static final String REGEX_SCRIPT = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式
private static final String REGEX_STYLE = "<style[^>]*?>[\\s\\S]*?<\\/style>"; // 定义style的正则表达式
private static final String REGEX_HTML = "<[^>]+>"; // 定义HTML标签的正则表达式
// private static final String REGEX_SPACE = "\\s*|\t|\r|\n";// 定义空格回车换行符
/**
* 过滤掉script标签
*
* @param htmlStr
* @return
*/
public static String delScriptTag(String htmlStr) {
if (htmlStr == null)
return null;
Pattern p_script = Pattern.compile(REGEX_SCRIPT, Pattern.CASE_INSENSITIVE);
Matcher m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); // 过滤script标签
return htmlStr;
}
/**
* 过滤掉style标签
*
* @param htmlStr
* @return
*/
public static String delStyleTag(String htmlStr) {
if (htmlStr == null)
return null;
Pattern p_style = Pattern.compile(REGEX_STYLE, Pattern.CASE_INSENSITIVE);
Matcher m_style = p_style.matcher(htmlStr);
htmlStr = m_style.replaceAll(""); // 过滤style标签*/
return htmlStr;
}
/**
* @param htmlStr
* @return 删除Html标签
*/
public static String delHTMLTag(String htmlStr) {
if (htmlStr == null)
return null;
Pattern p_html = Pattern.compile(REGEX_HTML, Pattern.CASE_INSENSITIVE);
Matcher m_html = p_html.matcher(htmlStr);
htmlStr = m_html.replaceAll(""); // 过滤html标签
return htmlStr; // 返回文本字符串
}
/**
* 将html标签中的<>进行转义,如只有"<"或者">"则不进行转义
*/
public static String escapeHtml(String htmlStr) {
if (htmlStr == null)
return null;
Pattern p_script = Pattern.compile(REGEX_HTML, Pattern.CASE_INSENSITIVE);
Matcher m_script = p_script.matcher(htmlStr);
while (m_script.find()) {
String str = m_script.group();
String str_target = str.replaceAll("<", "<").replaceAll(">", ">");
htmlStr = htmlStr.replaceAll(str, str_target);
}
return htmlStr;
}
/**
* 转义html标签
*
* @param input
* @return
*/
public static String cleanXss(String input) {
if (input == null)
return null;
return escapeHtml(delStyleTag(delScriptTag(input)));
}
public static void main(String[] args) {
System.out.println(cleanXss("<'script>"));
// escapeStr("<是打发第三方>1212<sdf>《dd》<dd");
}
}
- web.xml配置示例
<filter>
<filter-name>xssFilterChain</filter-name>
<filter-class>xxxxxxx.xxxxxx.XssFiter</filter-class>
</filter>
<filter-mapping>
<filter-name>xssFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- XssUtil类中主要给出了过滤掉script标签、style标签的内容,以及将html标签中的<>转义为<>,在使用中可根据实际情况,重写cleanXss方法