淺談Springboot2.0防止XSS攻擊的幾種方式
在平時(shí)做項(xiàng)目代碼開發(fā)的時(shí)候,很容易忽視XSS攻擊的防護(hù),網(wǎng)上有很多自定義全局?jǐn)r截器來實(shí)現(xiàn)XSS過濾,其實(shí)不需要這么麻煩,SpringBoot留有不少鉤子(擴(kuò)展點(diǎn)),據(jù)此我們可以巧妙地實(shí)現(xiàn)全局的XSS過濾
防止XSS攻擊,一般有兩種做法:
轉(zhuǎn)義
使用工具類HtmlUtils實(shí)現(xiàn)
過濾
將敏感標(biāo)簽去除
jsoup實(shí)現(xiàn)了非常強(qiáng)大的clean敏感標(biāo)簽的功能
轉(zhuǎn)義 做法的三種實(shí)現(xiàn):
轉(zhuǎn)義方法一:注冊(cè)自定義轉(zhuǎn)換器
自定義轉(zhuǎn)換器,集成PropertyEditorSupport類實(shí)現(xiàn),轉(zhuǎn)換器還可以實(shí)現(xiàn)數(shù)據(jù)格式轉(zhuǎn)換,例如:date的轉(zhuǎn)換;
@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);
? ? ? ? // 注冊(cè)自定義的類型轉(zhuǎn)換器
? ? ? ? binder.registerCustomEditor(Date.class, dateEditor);
? ? ? ? binder.registerCustomEditor(String.class, stringEscapeEditor);
? ? }
}轉(zhuǎn)義方法二:BaseController
需要XSS防護(hù)的Controller的需要繼承該BaseController
public class BaseController {
?
? ? @Autowired
? ? private StringEscapeEditor stringEscapeEditor;
?
? ? @InitBinder
? ? public void initBinder(ServletRequestDataBinder binder) {
? ? ? ? binder.registerCustomEditor(String.class, stringEscapeEditor);
? ? }
}轉(zhuǎn)義方法三:Converter
@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;
/**
* 在參數(shù)綁定時(shí),自定義String->String的轉(zhuǎn)換器,
* 在轉(zhuǎn)換邏輯中對(duì)參數(shù)值進(jìn)行轉(zhuǎn)義,從而達(dá)到防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);
}
}到此這篇關(guān)于淺談Springboot2.0防止XSS攻擊的幾種方式的文章就介紹到這了,更多相關(guān)Springboot防止XSS攻擊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解關(guān)于SpringBoot的外部化配置使用記錄
這篇文章主要介紹了詳解關(guān)于SpringBoot的外部化配置使用記錄,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
MyBatis中selectKey標(biāo)簽及主鍵回填實(shí)現(xiàn)
<selectKey>標(biāo)簽在MyBatis中提供了一種靈活的方式來生成和回填主鍵,本文就來介紹一下selectKey標(biāo)簽及主鍵回填實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-12-12
Mybatis中typeAliases標(biāo)簽和package標(biāo)簽使用
這篇文章主要介紹了Mybatis中typeAliases標(biāo)簽和package標(biāo)簽使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Java 實(shí)戰(zhàn)練手項(xiàng)目之醫(yī)院預(yù)約掛號(hào)系統(tǒng)的實(shí)現(xiàn)流程
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SpringBoot+Maven+Vue+mysql實(shí)現(xiàn)一個(gè)醫(yī)院預(yù)約掛號(hào)系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11
Java程序初始化啟動(dòng)自動(dòng)執(zhí)行的三種方式
這篇文章主要介紹了Java程序初始化啟動(dòng)自動(dòng)執(zhí)行的三種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
Java靜態(tài)static關(guān)鍵字原理詳解
這篇文章主要介紹了Java靜態(tài)static關(guān)鍵字原理詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12

