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;i
2.创建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
publicClasshandledType(){
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实现主题,但是思路是一致的,不限于任何框架.
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!