在使用@RequestBody情况SpringBoot 参数并不是封装在parameter里面,所以重写getParameterValues和getParameterValue并不能解决问题,@RequestBody是流的形式,所以写Xss过滤如下:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Document.OutputSettings;
import org.jsoup.safety.Whitelist;
import org.springframework.util.StreamUtils;
import com.alibaba.fastjson.JSONObject;
/**
* XSS过滤处理
*
* @author ruoyi
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private static final Whitelist whitelist = createWhitelist();
private static final OutputSettings outputSettings = new Document.OutputSettings().prettyPrint(false);
private byte[] requestBody;
private Charset charSet;
private static Whitelist createWhitelist() {
return Whitelist.relaxed()
.removeProtocols("a", "href", "ftp", "http", "https", "mailto")
.removeProtocols("img", "src", "http", "https")
.addAttributes("a", "href", "title", "target") // 官方默认会将 target 给过滤掉
/**
* 在 Whitelist.relaxed() 之外添加额外的白名单规则
*/
.addTags("div", "span", "embed", "object", "param")
.addAttributes(":all", "style", "class", "id", "name")
.addAttributes("object", "width", "height", "classid", "codebase")
.addAttributes("param", "name", "value")
.addAttributes("embed", "src", "quality", "width", "height", "allowFullScreen", "allowScriptAccess", "flashvars", "name", "type", "pluginspage");
}
private static String[] filter(String[] values) {
if ( values != null ) {
for ( int i = 0, len = values.length; i < len; i++ ) {
if ( values[i] != null && !"".equals(values[i]) ) {
values[i] = Jsoup.clean(values[i], "", whitelist, outputSettings).trim();
}
}
}
return values;
}
private static String filter(String value) {
if(value!=null) {
value = Jsoup.clean(value, "", whitelist, outputSettings).trim();
}
return value;
}
/**
* @param request
*/
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
//缓存请求body
try {
String requestBodyStr = getRequestPostStr(request);
if (StringUtils.isNotBlank(requestBodyStr)) {
requestBodyStr=filter(requestBodyStr);
JSONObject resultJson = JSONObject.parseObject(requestBodyStr);
requestBody = resultJson.toString().getBytes(charSet);
} else {
requestBody = new byte[0];
}
} catch (IOException e) {
e.printStackTrace();
}
}
public String getRequestPostStr(HttpServletRequest request)
throws IOException {
String charSetStr = request.getCharacterEncoding();
if (charSetStr == null) {
charSetStr = "UTF-8";
}
charSet = Charset.forName(charSetStr);
return StreamUtils.copyToString(request.getInputStream(), charSet);
}
public ServletInputStream getInputStream() {
if (requestBody == null) {
requestBody = new byte[0];
}
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
}
再加上个filter:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
/**
* xss 过滤器
*
* @author imsjw
* Create Time: 2018/8/10
*/
public class XssFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
chain.doFilter(xssRequest, response);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
配置filter的地方:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean filterRegist() {
FilterRegistrationBean frBean = new FilterRegistrationBean();
frBean.setFilter(new XssFilter());
frBean.addUrlPatterns("/*");
return frBean;
}
}
OK,大功告成。测试一下,确实是可以过滤掉script,alert这种东西。
本文介绍了在SpringBoot中,针对@RequestBody注解处理请求参数时,由于参数以流形式存在,无法直接通过常规方式过滤Xss。文中提供了一种过滤方案,包括实现Xss过滤的filter及配置步骤,测试验证可以有效阻止script,alert等Xss攻击。"
112585190,10544741,5G双连接技术:5G与LTE协同增强网络性能,"['5G网络', '双连接技术', '网络规划', '移动通信']

1万+

被折叠的 条评论
为什么被折叠?



