使用springMVC通过Filter实现防止xss注入

springMVC Filter防止xss注入 跨站脚本工具(cross 斯特scripting),为不和层叠样式表(cascading style sheets,CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。
恶意攻击者往web页面里插入恶意scriptScript代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
防止XSS攻击简单的预防就是对Request请求中的一些参数去掉一些比较敏感的脚本命令。
原本是打算通过springMVC的HandlerInterceptor机制来实现的,通过获取request然后对request中的参数进行修改,结果虽然值修改了,但在Controller中获取的数值还是没有修改的。没办法就是要Filter来完成。
简单来说就是创建一个新的httpRequest类XsslHttpServletRequestWrapper,然后重写一些get方法(获取参数时对参数进行XSS判断预防)。

@WebFilter(filterName="xssMyfilter",urlPatterns="/*") public class MyXssFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {XsslHttpServletRequestWrapper xssRequest = new XsslHttpServletRequestWrapper((HttpServletRequest)request); chain.doFilter(xssRequest , response); } @Override public void destroy() { } }

XSS代码的过滤是在XsslHttpServletRequestWrapper中实现的,主要是覆盖实现了getParameter,getParameterValues,getHeader这几个方法,然后对获取的value值进行XSS处理。
public class XsslHttpServletRequestWrapper extends HttpServletRequestWrapper { HttpServletRequest xssRequest = null; public XsslHttpServletRequestWrapper(HttpServletRequest request) {super(request); xssRequest = request; } @Overridepublic String getParameter(String name) {String value = https://www.it610.com/article/super.getParameter(replaceXSS(name)); if (value != null) {value = replaceXSS(value); }return value; }@Override public String[] getParameterValues(String name) {String[] values = super.getParameterValues(replaceXSS(name)); if(values != null && values.length> 0){for(int i =0; i< values.length ; i++){values[i] = replaceXSS(values[i]); }}return values; }@Overridepublic String getHeader(String name) {String value = https://www.it610.com/article/super.getHeader(replaceXSS(name)); if (value != null) {value = replaceXSS(value); }return value; } /*** 去除待带script、src的语句,转义替换后的value值*/ public static String replaceXSS(String value) {if (value != null) {try{value = value.replace("+","%2B"); //'+' replace to '%2B'value = https://www.it610.com/article/URLDecoder.decode(value,"utf-8"); }catch(UnsupportedEncodingException e){}catch(IllegalArgumentException e){}// Avoid null charactersvalue = https://www.it610.com/article/value.replaceAll("\0", ""); // Avoid anything between script tagsPattern scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE); value = https://www.it610.com/article/scriptPattern.matcher(value).replaceAll(""); // Avoid anything in a src='https://www.it610.com/article/...' type of e-xpressionscriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = https://www.it610.com/article/scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = https://www.it610.com/article/scriptPattern.matcher(value).replaceAll(""); // Remove any lonesometagscriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE); value = https://www.it610.com/article/scriptPattern.matcher(value).replaceAll(""); // Remove any lonesometagscriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = https://www.it610.com/article/scriptPattern.matcher(value).replaceAll(""); // Avoid eval(...) e-xpressionsscriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = https://www.it610.com/article/scriptPattern.matcher(value).replaceAll(""); // Avoid e-xpression(...) e-xpressionsscriptPattern = Pattern.compile("e-xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = https://www.it610.com/article/scriptPattern.matcher(value).replaceAll(""); // Avoid javascript:... e-xpressionsscriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE); value = https://www.it610.com/article/scriptPattern.matcher(value).replaceAll(""); // Avoid alert:... e-xpressionsscriptPattern = Pattern.compile("alert", Pattern.CASE_INSENSITIVE); value = https://www.it610.com/article/scriptPattern.matcher(value).replaceAll(""); // Avoid οnlοad= e-xpressionsscriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); value = https://www.it610.com/article/scriptPattern.matcher(value).replaceAll(""); scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE); value = https://www.it610.com/article/scriptPattern.matcher(value).replaceAll(""); }return filter(value); }/*** 过滤特殊字符*/public static String filter(String value) {if (value =https://www.it610.com/article/= null) {return null; }StringBuffer result = new StringBuffer(value.length()); for (int i=0; i': result.append(">"); break; case '"': result.append("""); break; case '\'': result.append("'"); break; case '%': result.append("%"); break; case '; ': result.append("; "); break; case '(': result.append("("); break; case ')': result.append(")"); break; case '&': result.append("&"); break; case '+':result.append("+"); break; default:result.append(value.charAt(i)); break; }}return result.toString(); } }

SpringMVC 防止XSS 工具(常规方式) 要求:
xss过滤请求的参数:Content-Type为 json(application/json)
SpringMVC 对于application/json 转换处理说明:
spring mvc默认使用MappingJackson2HttpMessageConverter转换器,
而它是使用jackson来序列化对象的,如果我们能 将jackson的序列化和反序列化过程修改,加入过滤xss代码,并将其注册到MappingJackson2HttpMessageConverter中
具体实现功能代码:
import java.io.IOException; import org.apache.commons.text.StringEscapeUtils; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; /** * 反序列化 * */public class XssDefaultJsonDeserializer extends StdDeserializer { public XssDefaultJsonDeserializer(){this(null); } public XssDefaultJsonDeserializer(Class vc) {super(vc); } @Override public String deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {// TODO Auto-generated method stub//return StringEscapeUtils.escapeEcmaScript(jsonParser.getText()); return StringEscapeUtils.unescapeHtml4(jsonParser.getText()); } }

SpringMVC 配置对象:
@Configuration@EnableWebMvcpublic class SpingMVCConfig extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters(List> converters) {super.configureMessageConverters(converters); // TODO Auto-generated method stubSimpleModule module = new SimpleModule(); // 反序列化module.addDeserializer(String.class, new XssDefaultJsonDeserializer()); // 序列化module.addSerializer(String.class, new XssDefaultJsonSerializer()); ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().build(); // 注册自定义的序列化和反序列化器mapper.registerModule(module); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(mapper); converters.add(converter); }}

【使用springMVC通过Filter实现防止xss注入】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    推荐阅读