JSP spring boot / cloud 使用filter防止XSS
JSPspringboot/cloud使用filter防止XSS
一.前言
XSS(跨站脚本攻击)
跨站脚本攻击(CrossSiteScripting),为不和层叠样式表(CascadingStyleSheets,CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
二.思路
基于filter拦截,将特殊字符替换为html转意字符(如:"<"转意为"<"),需要拦截的点如下:
- 请求头requestHeader
- 请求体requestBody
- 请求参数requestParameter
三.实现
1.创建XssHttpServletRequestWrapper类
在获取请求头,请求参数的这些地方,将目标值使用HtmlUtils.htmlEscape方法转意为html字符,而避免恶意代码参与到后续的流程中
/** *XssHttpServletRequestWrapper.java *Createdat2016-09-19 *Createdbywangkang *Copyright(C)2016egridcloud.com,Allrightsreserved. */ packagecom.egridcloud.udf.core.xss; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletRequestWrapper; importorg.springframework.web.util.HtmlUtils; /** *描述:跨站请求防范 * *@authorwangkang * */ publicclassXssHttpServletRequestWrapperextendsHttpServletRequestWrapper{ /** *描述:构造函数 * *@paramrequest请求对象 */ publicXssHttpServletRequestWrapper(HttpServletRequestrequest){ super(request); } @Override publicStringgetHeader(Stringname){ Stringvalue=super.getHeader(name); returnHtmlUtils.htmlEscape(value); } @Override publicStringgetParameter(Stringname){ Stringvalue=super.getParameter(name); returnHtmlUtils.htmlEscape(value); } @Override publicString[]getParameterValues(Stringname){ String[]values=super.getParameterValues(name); if(values!=null){ intlength=values.length; String[]escapseValues=newString[length]; for(inti=0;i2.创建XssStringJsonSerializer类
其次是涉及到json转换的地方,也一样需要进行转意,比如,rerquestBody,responseBody
/** *XssStringJsonSerializer.java *Createdat2016-09-19 *Createdbywangkang *Copyright(C)2016egridcloud.com,Allrightsreserved. */ packagecom.egridcloud.udf.core.xss; importjava.io.IOException; importorg.springframework.web.util.HtmlUtils; importcom.fasterxml.jackson.core.JsonGenerator; importcom.fasterxml.jackson.databind.JsonSerializer; importcom.fasterxml.jackson.databind.SerializerProvider; /** *描述:基于xss的JsonSerializer * *@authorwangkang * */ publicclassXssStringJsonSerializerextendsJsonSerializer{ @Override publicClass handledType(){ returnString.class; } @Override publicvoidserialize(Stringvalue,JsonGeneratorjsonGenerator, SerializerProviderserializerProvider)throwsIOException{ if(value!=null){ StringencodedValue=HtmlUtils.htmlEscape(value); jsonGenerator.writeString(encodedValue); } } } 3.创建Bean
在启动类中,创建XssObjectMapper的bean,替换springboot原有的实例,用于整个系统的json转换.
/** *描述:xssObjectMapper * *@parambuilderbuilder *@returnxssObjectMapper */ @Bean @Primary publicObjectMapperxssObjectMapper(Jackson2ObjectMapperBuilderbuilder){ //解析器 ObjectMapperobjectMapper=builder.createXmlMapper(false).build(); //注册xss解析器 SimpleModulexssModule=newSimpleModule("XssStringJsonSerializer"); xssModule.addSerializer(newXssStringJsonSerializer()); objectMapper.registerModule(xssModule); //返回 returnobjectMapper; }4.创建XssFilter
首先是拦截所有的请求,然后在doFilter方法中,将HttpServletRequest强制类型转换成XssHttpServletRequestWrapper
然后传递下去.
/** *XssFilter.java *Createdat2016-09-19 *Createdbywangkang *Copyright(C)2016egridcloud.com,Allrightsreserved. */ packagecom.egridcloud.udf.core.xss; importjava.io.IOException; importjavax.servlet.Filter; importjavax.servlet.FilterChain; importjavax.servlet.FilterConfig; importjavax.servlet.ServletException; importjavax.servlet.ServletRequest; importjavax.servlet.ServletResponse; importjavax.servlet.annotation.WebFilter; importjavax.servlet.http.HttpServletRequest; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; /** *描述:跨站请求防范 * *@authorwangkang * */ @WebFilter(filterName="xssFilter",urlPatterns="/*",asyncSupported=true) publicclassXssFilterimplementsFilter{ /** *描述:日志 */ privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(XssFilter.class); @Override publicvoidinit(FilterConfigfilterConfig)throwsServletException{ LOGGER.debug("(XssFilter)initialize"); } @Override publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain) throwsIOException,ServletException{ XssHttpServletRequestWrapperxssRequest= newXssHttpServletRequestWrapper((HttpServletRequest)request); chain.doFilter(xssRequest,response); } @Override publicvoiddestroy(){ LOGGER.debug("(XssFilter)destroy"); } }四.结束
本文虽基于springboot实现主题,但是思路是一致的,不限于任何框架.
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!