springboot解決XSS存儲(chǔ)型漏洞問(wèn)題
XSS攻擊
XSS 攻擊
跨站腳本攻擊(Cross Site Scripting),為不和 前端層疊樣式表(Cascading Style Sheets)CSS 混淆,故將跨站腳本攻擊縮寫為 XSS。
XSS(跨站腳本攻擊)
是指惡意攻擊者往 Web 頁(yè)面里插入惡意 Script 代碼,當(dāng)用戶瀏覽該頁(yè)時(shí),嵌入其中 Web 里面的 Script 代碼會(huì)被執(zhí)行,從而達(dá)到惡意攻擊用戶的目的。
類似于 sql 注入。是目前最普遍的 Web 應(yīng)用安全漏洞,也是 Web 攻擊中最常見的攻擊方式之一。
XSS( 跨站腳本攻擊)攻擊通常指的是通過(guò)利用網(wǎng)頁(yè)開發(fā)時(shí)留下的漏洞,通過(guò)巧妙的方法注入惡意指令代碼到網(wǎng)頁(yè),使用戶加載并執(zhí)行攻擊者惡意制造的網(wǎng)頁(yè)程序。
這些惡意網(wǎng)頁(yè)程序通常是 JavaScript,但實(shí)際上也可以包括 Java、 VBScript、ActiveX、 Flash 或者甚至是普通的 HTML。
攻擊成功后,攻擊者可能得到包括但不限于更高的權(quán)限(如執(zhí)行一些操作)、私密網(wǎng)頁(yè)內(nèi)容、會(huì)話和 cookie 等各種內(nèi)容。
XSS攻擊示例


過(guò)濾請(qǐng)求非法內(nèi)容XSS類:XssRequestWrappers
這個(gè)類用來(lái)過(guò)濾請(qǐng)求非法內(nèi)容,詳細(xì)代碼如下:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
/**
* @ClassName XssRequestWrappers
* @Description TODO
* @Author tongxueqiyue
* @Date 2023/12/18 10:43
* @Version 1.0
*/
public class XssRequestWrappers extends HttpServletRequestWrapper {
private CommonsMultipartResolver multiparResolver = new CommonsMultipartResolver();
public XssRequestWrappers(HttpServletRequest request) {
super(request);
String type = request.getHeader("Content-Type");
if (!StringUtils.isEmpty(type) && type.contains("multipart/form-data")) {
MultipartHttpServletRequest multipartHttpServletRequest = multiparResolver.resolveMultipart(request);
Map<String, String[]> stringMap = multipartHttpServletRequest.getParameterMap();
if (!stringMap.isEmpty()) {
for (String key : stringMap.keySet()) {
String value = multipartHttpServletRequest.getParameter(key);
striptXSS(key);
striptXSS(value);
}
}
super.setRequest(multipartHttpServletRequest);
}
}
@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] = striptXSS(values[i]);
}
return encodedValues;
}
@Override
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
return striptXSS(value);
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
return striptXSS(value);
}
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> map1 = super.getParameterMap();
Map<String, String[]> escapseMap = new HashMap<String, String[]>();
Set<String> keys = map1.keySet();
for (String key : keys) {
String[] valArr = map1.get(key);
if (valArr != null && valArr.length > 0) {
String[] escapseValArr = new String[valArr.length];
for (int i = 0; i < valArr.length; i++) {
String escapseVal = striptXSS(valArr[i]);
escapseValArr[i] = escapseVal;
}
escapseMap.put(key, escapseValArr);
}
}
return escapseMap;
}
//處理非法內(nèi)容,如果有新的在此處增加即可
public static String striptXSS(String value) {
if (value != null) {
// 替換空字符串,以便清除潛在的惡意腳本
value = value.replaceAll("", "");
// 移除<script>標(biāo)簽及其內(nèi)容
Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// 移除帶有src屬性的標(biāo)簽,支持單引號(hào)和雙引號(hào)包圍的屬性值
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// 移除</script>標(biāo)簽
scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// 移除以<script...>開頭的標(biāo)簽
scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// 移除eval()函數(shù)調(diào)用
scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// 移除expression()函數(shù)調(diào)用
scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// 移除以"javascript:"開頭的字符串
scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// 移除以"vbscript:"開頭的字符串
scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// 移除以"onload..."開頭的字符串
scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// 移除包含任何<和>字符的字符串
scriptPattern = Pattern.compile(".*<.*", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
}
// 返回處理后的字符串
return value;
}
}
定義過(guò)濾器監(jiān)聽XSSFilter 重寫Filter
在這個(gè)過(guò)濾器中監(jiān)聽XSSFilter,使用上面寫的XssRequestWrappers來(lái)處理請(qǐng)求中的非法內(nèi)容
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;
/**
* @ClassName XSSFilter
* @Description TODO
* @Author tongxueqiyue
* @Date 2023/12/18 10:45
* @Version 1.0
*/
public class XSSFilter implements Filter {
@Override
public void init(FilterConfig arg0) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(new XssRequestWrappers((HttpServletRequest) request), response);
}
}
注冊(cè)這個(gè)XSSFilter為Bean
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean<XSSFilter> xssFilterRegistrationBean() {
FilterRegistrationBean<XSSFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new XSSFilter());
registrationBean.addUrlPatterns("/*"); // 這里配置需要過(guò)濾的URL
registrationBean.setName("xssFilter");
registrationBean.setOrder(1); // 設(shè)置過(guò)濾器的執(zhí)行順序,數(shù)字越小越優(yōu)先
return registrationBean;
}
}
執(zhí)行這三步應(yīng)該就可以了,不過(guò)啟動(dòng)可能會(huì)報(bào)錯(cuò),如果報(bào)錯(cuò)添加以下依賴即可:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
到這里XSS存儲(chǔ)型漏洞應(yīng)該就能解決了
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring MVC 文件、cookies的接收 與REST響應(yīng)詳
在SpringMVC中,使用@RequestPart注解可接收文件并處理多部分請(qǐng)求,同時(shí)可以通過(guò)@CookieValue和HttpServletResponse來(lái)獲取和設(shè)置Cookies,本文介紹Spring MVC 文件、cookies的接收 與REST響應(yīng),感興趣的朋友跟隨小編一起看看吧2024-09-09
看過(guò)就懂的java零拷貝及實(shí)現(xiàn)方式詳解
這篇文章主要為大家詳細(xì)的介紹了什么是零拷貝,傳統(tǒng)的IO執(zhí)行流程,零拷貝相關(guān)的知識(shí)點(diǎn)回顧,零拷貝實(shí)現(xiàn)的幾種方式及java提供的零拷貝方式相關(guān)內(nèi)容,有需要的朋友可以借鑒參考下2022-01-01
SpringBoot實(shí)現(xiàn)登錄攔截器的方法詳解
其實(shí)spring?boot攔截器的配置方式和springMVC差不多,只有一些小的改變需要注意下就ok了。本文主要給大家介紹了關(guān)于如何在Springboot實(shí)現(xiàn)登陸攔截器功能,需要的朋友可以參考下2022-07-07
JDK1.6“新“特性Instrumentation之JavaAgent(推薦)
這篇文章主要介紹了JDK1.6“新“特性Instrumentation之JavaAgent,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
SpringBoot統(tǒng)計(jì)、監(jiān)控SQL運(yùn)行情況的方法詳解
這篇文章主要給大家介紹了關(guān)于SpringBoot統(tǒng)計(jì)、監(jiān)控SQL運(yùn)行情況的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02
javamail實(shí)現(xiàn)注冊(cè)激活郵件
這篇文章主要為大家詳細(xì)介紹了javamail實(shí)現(xiàn)注冊(cè)激活郵件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
你必須得會(huì)的SpringBoot全局統(tǒng)一處理異常詳解
程序在運(yùn)行的過(guò)程中,不可避免會(huì)產(chǎn)生各種各樣的錯(cuò)誤,這個(gè)時(shí)候就需要進(jìn)行異常處理,本文主要為大家介紹了SpringBoot實(shí)現(xiàn)全局統(tǒng)一處理異常的方法,需要的可以參考一下2023-06-06

