背景:过滤xss攻击,同时将过滤后的日志输出到指定文件。(指定文件输出请看上篇博文)
前景:利用filter进行xss攻击过滤,需要应对不同请求做不同的过滤处理,若是post请求的json格式数据,需要重写getinputstream方法(因为流读取一次后,下层controller无法再次进行读取。原理可自行百度)
因此需要重写两个wrapper(继承HttpServletRequestWrapper)(针对post的json请求以及其他格式的请求)
在filter中以contentType做类型的区分
未做业务耦合的区分(日志输出与xss过滤耦合到一起),若要区分开功能,单独书写即可
一:重写wrapper
1:contentType为multipart/form-data或application/x-www-form-urlencoded
public class XSSNormalRequestWrapper extends HttpServletRequestWrapper {
public XSSNormalRequestWrapper(HttpServletRequest request) {
super(request);
}
@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] = stripXSS(values[i]);
}
return encodedValues;
}
@Override
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
return stripXSS(value);
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
return stripXSS(value);
}
}
2:contentType为application/json
public class XSSBodyRequestWrapper extends HttpServletRequestWrapper {
private String body;
public XSSBodyRequestWrapper(HttpServletRequest request) {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
InputStream inputStream = null;
try {
inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, by