web安全中,xss防御是比较稀疏平常的。
在使用springboot中,类似于普通的参数parameter,attribute,header一类的,可以直接使用过滤器来过滤。而前端发送回来的json字符串貌似没那么方便过滤了。
一般在springboot中,前端传递json,后端使用@RequestBody来接收;而后端响应json发送至前端,则会使用@ResponseBody。
这里考虑用自定义json消息解析器来过滤前端传递或者后端响应的json。
1、首先创建一个自定义json消息解析器:
import java.io.IOException;
import java.lang.reflect.Type;
import com.weymay.index.common.util.StringUtil;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import com.fasterxml.jackson.databind.JavaType;
/**
* 过滤json中的特殊字符避免xss攻击的消息解析器
* Created by Nemo on 2017/10/10.
*/
public class XSSMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
/**
* 读取json参数时处理
* @param type
* @param contextClass
* @param inputMessage
* @return
* @throws IOException
* @throws HttpMessageNotReadableException
*/
@Override
public Object read(Type type, Class contextClass,
HttpInputMessage inputMessage) throws IOException,
HttpMessageNotReadableException {
JavaType javaType = getJavaType(type, contextClass);
Object obj = readJavaType(javaType, inputMessage);
//得到请求json
String json = super.getObjectMapper().writeValueAsString(obj);
//过滤特殊字符
String result = StringUtil.filterDangerString(json);
Object resultObj = super.getObjectMapper().readValue(result, javaType);
return resultObj;
}
/**
*
* @param javaType
* @param inputMessage
* @return
*/
private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) {
try {
return super.getObjectMapper().readValue(inputMessage.getBody(), javaType);
} catch (IOException ex) {
throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex);
}
}
/**
* 输出json时处理
* @param object
* @param outputMessage
* @throws IOException
* @throws HttpMessageNotWritableException
*/
@Override
protected void writeInternal(Object object, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
//得到要输出的json
String json = super.getObjectMapper().writeValueAsString(object);
//过滤特殊字符
String result = StringUtil.filterDangerString(json.toString());
// 输出
outputMessage.getBody().write(result.getBytes());
}
}
这里省略掉了过滤特殊字符的操作工具。
2、直接在springboot启动的时候,加载自定义json消息解析器,用来处理json。在启动类中添加:
@Bean
public HttpMessageConverters xssHttpMessageConverters() {
XSSMappingJackson2HttpMessageConverter xssMappingJackson2HttpMessageConverter = new XSSMappingJackson2HttpMessageConverter();
HttpMessageConverter converter = xssMappingJackson2HttpMessageConverter;
return new HttpMessageConverters(converter);
}
即可。
普通的参数可以创建过滤器来过滤,这里便不再细细写了。
没图不好看,附个图: