springboot解決XSS存儲型漏洞問題
XSS攻擊
XSS 攻擊
跨站腳本攻擊(Cross Site Scripting),為不和 前端層疊樣式表(Cascading Style Sheets)CSS 混淆,故將跨站腳本攻擊縮寫為 XSS。
XSS(跨站腳本攻擊)
是指惡意攻擊者往 Web 頁面里插入惡意 Script 代碼,當(dāng)用戶瀏覽該頁時,嵌入其中 Web 里面的 Script 代碼會被執(zhí)行,從而達(dá)到惡意攻擊用戶的目的。
類似于 sql 注入。是目前最普遍的 Web 應(yīng)用安全漏洞,也是 Web 攻擊中最常見的攻擊方式之一。
XSS( 跨站腳本攻擊)攻擊通常指的是通過利用網(wǎng)頁開發(fā)時留下的漏洞,通過巧妙的方法注入惡意指令代碼到網(wǎng)頁,使用戶加載并執(zhí)行攻擊者惡意制造的網(wǎng)頁程序。
這些惡意網(wǎng)頁程序通常是 JavaScript,但實際上也可以包括 Java、 VBScript、ActiveX、 Flash 或者甚至是普通的 HTML。
攻擊成功后,攻擊者可能得到包括但不限于更高的權(quán)限(如執(zhí)行一些操作)、私密網(wǎng)頁內(nèi)容、會話和 cookie 等各種內(nèi)容。
XSS攻擊示例
過濾請求非法內(nèi)容XSS類:XssRequestWrappers
這個類用來過濾請求非法內(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)簽,支持單引號和雙引號包圍的屬性值 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; } }
定義過濾器監(jiān)聽XSSFilter 重寫Filter
在這個過濾器中監(jiān)聽XSSFilter,使用上面寫的XssRequestWrappers來處理請求中的非法內(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); } }
注冊這個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("/*"); // 這里配置需要過濾的URL registrationBean.setName("xssFilter"); registrationBean.setOrder(1); // 設(shè)置過濾器的執(zhí)行順序,數(shù)字越小越優(yōu)先 return registrationBean; } }
執(zhí)行這三步應(yīng)該就可以了,不過啟動可能會報錯,如果報錯添加以下依賴即可:
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency>
到這里XSS存儲型漏洞應(yīng)該就能解決了
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring MVC 文件、cookies的接收 與REST響應(yīng)詳
在SpringMVC中,使用@RequestPart注解可接收文件并處理多部分請求,同時可以通過@CookieValue和HttpServletResponse來獲取和設(shè)置Cookies,本文介紹Spring MVC 文件、cookies的接收 與REST響應(yīng),感興趣的朋友跟隨小編一起看看吧2024-09-09JDK1.6“新“特性Instrumentation之JavaAgent(推薦)
這篇文章主要介紹了JDK1.6“新“特性Instrumentation之JavaAgent,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08SpringBoot統(tǒng)計、監(jiān)控SQL運(yùn)行情況的方法詳解
這篇文章主要給大家介紹了關(guān)于SpringBoot統(tǒng)計、監(jiān)控SQL運(yùn)行情況的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2022-02-02你必須得會的SpringBoot全局統(tǒng)一處理異常詳解
程序在運(yùn)行的過程中,不可避免會產(chǎn)生各種各樣的錯誤,這個時候就需要進(jìn)行異常處理,本文主要為大家介紹了SpringBoot實現(xiàn)全局統(tǒng)一處理異常的方法,需要的可以參考一下2023-06-06