SpringBoot只需要几行代码,就可以防XSS攻击
程序员文章站
2022-06-19 14:47:42
前言可能很多同学在学习过程中自己做项目,很容易忽略XSS攻击。网上不少博客的自定义全局拦截器来实现XSS过滤,其实不需要这么麻烦,SpringBoot留有不少钩子(扩展点),据此我们可以巧妙地实现全局的XSS过滤。防止XSS攻击,一般有两种做法:1、转义Spring有提供工具类HtmlUtils来实现转义。个人比较喜欢这种方式,所以下面代码均采用转义处理。2、过滤敏感标签(将敏感标签去除)jsoup实现了非常强大的clean敏感标签的功能,但是我对jsoup了解并不多。接下来的...
前言
可能很多同学在学习过程中自己做项目,很容易忽略XSS攻击。网上不少博客的自定义全局拦截器来实现XSS过滤,其实不需要这么麻烦,SpringBoot留有不少钩子(扩展点),据此我们可以巧妙地实现全局的XSS过滤。
防止XSS攻击,一般有两种做法:
1、转义
Spring有提供工具类HtmlUtils来实现转义。个人比较喜欢这种方式,所以下面代码均采用转义处理。
2、过滤敏感标签(将敏感标签去除)
jsoup实现了非常强大的clean敏感标签的功能,但是我对jsoup了解并不多。
接下来的问题,就是:不适用拦截器,在哪切入,对参数进行转义处理呢?答案是:SpringMVC 进行参数绑定时!关于源码级别的理解和说明,我就不说了,因为能力有限。详情可参考:https://www.cnblogs.com/yourbatman/p/11218694.html
下面我会提供3种配置方式!个人比较推荐 方式3,因为WebMvcConfigurer本身就是为开发者定制的配置MVC的非常强大的扩展接口。
方式1
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.util.HtmlUtils;
import java.beans.PropertyEditorSupport;
/**
* String->String的类型转换器
*
* @author passerbyYSQ
* @create 2021-02-22 17:26
*/
@Component
public class EscapeStringEditor extends PropertyEditorSupport {
@Override
public String getAsText() {
Object value = getValue();
return value != null ? value.toString() : "";
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
String escapedText = null;
if (!StringUtils.isEmpty(text)) {
escapedText = HtmlUtils.htmlEscape(text, "UTF-8");
}
setValue(escapedText);
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
/**
* @author passerbyYSQ
* @create 2021-02-22 17:20
*/
@Component
public class MyWebBindingInitializer extends ConfigurableWebBindingInitializer {
@Autowired
private EscapeStringEditor escapeStringEditor;
@Override
public void initBinder(WebDataBinder binder) {
super.initBinder(binder); // 不能少!!!
// 注册自定义的类型转换器
binder.registerCustomEditor(String.class, escapeStringEditor);
}
}
方式2
public class BaseController {
@Autowired
private EscapeStringEditor escapeStringEditor;
@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
binder.registerCustomEditor(String.class, escapeStringEditor);
}
需要XSS防护的Controller的需要继承该BaseController
方式3
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.util.HtmlUtils;
/**
* @author passerbyYSQ
* @create 2021-02-22 23:15
*/
@Component
public class EscapeStringConverter implements Converter<String, String> {
@Override
public String convert(String s) {
return StringUtils.isEmpty(s) ? s : HtmlUtils.htmlEscape(s);
}
}
package net.ysq.webchat.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author passerbyYSQ
* @create 2021-01-29 14:41
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Autowired
private EscapeStringConverter escapeStringConverter;
/**
* 在参数绑定时,自定义String->String的转换器,
* 在转换逻辑中对参数值进行转义,从而达到防XSS的效果
*
* @param registry
*/
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(escapeStringConverter);
}
@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);
}
}
本文地址:https://blog.csdn.net/qq_43290318/article/details/113963435