赞
踩
Springboot2.0防止XSS攻击的几种方式
在平时做项目代码开发的时候,很容易忽视XSS攻击的防护,网上有很多自定义全局拦截器来实现XSS过滤,其实不需要这么麻烦,SpringBoot留有不少钩子(扩展点),据此我们可以巧妙地实现全局的XSS过滤
使用工具类HtmlUtils实现
将敏感标签去除
jsoup实现了非常强大的clean敏感标签的功能
自定义转换器,集成PropertyEditorSupport类实现,转换器还可以实现数据格式转换,例如:date的转换;
@Component
public class DateEditor extends PropertyEditorSupport {
Pattern pattern = Pattern.compile("[^0-9]");
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StrUtil.isBlank(text)) {
return;
}
text = text.trim();
Matcher matcher = pattern.matcher(text);
text = matcher.replaceAll("");
int length = text.length();
Date date;
switch (length) {
case 14:
date = DateTime.parse(text, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
break;
case 12:
date = DateTime.parse(text, DateTimeFormat.forPattern("yyyyMMddHHmm")).toDate();
break;
case 10:
date = DateTime.parse(text, DateTimeFormat.forPattern("yyyyMMddHH")).toDate();
break;
case 8:
date = DateTime.parse(text, DateTimeFormat.forPattern("yyyyMMdd")).toDate();
break;
case 6:
date = DateTime.parse(text, DateTimeFormat.forPattern("yyyyMM")).toDate();
break;
case 4:
date = DateTime.parse(text, DateTimeFormat.forPattern("yyyy")).toDate();
break;
default:
return;
}
setValue(date);
}
}
@Component
public class StringEscapeEditor extends PropertyEditorSupport {
public StringEscapeEditor() {
super();
}
@Override
public String getAsText() {
Object value = getValue();
return value != null ? value.toString() : "";
}
@Override
public void setAsText(String text) {
if (text == null) {
setValue(null);
} else {
String value = text;
value = value.trim();
setValue(value);
}
}
}
@Slf4j
@Component
public class CommentWebBindingInitializer extends ConfigurableWebBindingInitializer {
private final StringEscapeEditor stringEscapeEditor;
private final DateEditor dateEditor;
@Autowired
public CommentWebBindingInitializer(StringEscapeEditor stringEscapeEditor, DateEditor dateEditor) {
this.stringEscapeEditor = stringEscapeEditor;
this.dateEditor = dateEditor;
}
@Override
public void initBinder(WebDataBinder binder) {
log.info("init bind editor");
super.initBinder(binder);
// 注册自定义的类型转换器
binder.registerCustomEditor(Date.class, dateEditor);
binder.registerCustomEditor(String.class, stringEscapeEditor);
}
}
需要XSS防护的Controller的需要继承该BaseController
public class BaseController {
@Autowired
private StringEscapeEditor stringEscapeEditor;
@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
binder.registerCustomEditor(String.class, stringEscapeEditor);
}
}
@Component
public class StringEscapeEditor implements Converter<String, String> {
@Override
public String convert(String s) {
return StringUtils.isEmpty(s) ? s : HtmlUtils.htmlEscape(s);
}
}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Autowired
private StringEscapeEditor stringEscapeEditor;
/**
* 在参数绑定时,自定义String->String的转换器,
* 在转换逻辑中对参数值进行转义,从而达到防XSS的效果
*
* @param registry
*/
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(StringEscapeEditor);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**")
// 路径不包括contextPath部分
.excludePathPatterns("/user/login", "/user/logout", "/index/test1");
}
/**
* 前后端分离需要解决跨域问题
*
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")
.allowCredentials(true).maxAge(3600);
}
}
过滤做法参考链接:
使用jsoup方式: jsoup
转载链接:https://blog.csdn.net/changzhi9421/article/details/121693397
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。