SpringBoot去除參數(shù)前后空格和XSS過濾
去除XSS字符串需要借助工具類 jsoup ,這里jsoup有一點需要注意的是,jsoup的功能可能有點太強(qiáng)大了,能把xss攻擊的內(nèi)容直接過濾掉了不說,也會對英文尖括號<>轉(zhuǎn)義,到接口里面拿到的參數(shù)就變成了<>,存庫里面的就是轉(zhuǎn)義后的字符串了。取出來的時候需要轉(zhuǎn)一下。
比如前臺傳的參數(shù)傳的是: 12<>3<script>alter('11111111')</script>455
過濾處理了后,到后臺接口里面就成了:[12<>3455]
如果上面的結(jié)果能接受,那么這個工具類就可以用。
引入依賴 jsoup
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.12.1</version> </dependency>
JsoupUtil.java工具類:
import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.safety.Whitelist; /** * * @Auther linmengmeng * @Date 2021-08-19 15:47 * * 描述: 過濾 HTML 標(biāo)簽中 XSS 代碼 */ public class JsoupUtil { /** * 使用自帶的 basicWithImages 白名單 * 允許的便簽有 a,b,blockquote,br,cite,code,dd,dl,dt,em,i,li,ol,p,pre,q,small,span,strike,strong,sub,sup,u,ul,img * 以及 a 標(biāo)簽的 href,img 標(biāo)簽的 src,align,alt,height,width,title 屬性 */ private static final Whitelist whitelist = Whitelist.basicWithImages(); /** 配置過濾化參數(shù), 不對代碼進(jìn)行格式化 */ private static final Document.OutputSettings outputSettings = new Document.OutputSettings().prettyPrint(false); static { // 富文本編輯時一些樣式是使用 style 來進(jìn)行實現(xiàn)的 // 比如紅色字體 style="color:red;" // 所以需要給所有標(biāo)簽添加 style 屬性 whitelist.addAttributes(":all", "style"); } public static String clean(String content) { return Jsoup.clean(content, "", whitelist, outputSettings); } }
首先是定義參數(shù)過濾器:ParamsFilter 實現(xiàn) Filter 類
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; /** * Description : 參數(shù)過濾器 * */ public class ParamsFilter implements Filter { @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { ParameterRequestWrapper parmsRequest = new ParameterRequestWrapper( (HttpServletRequest) arg0); arg2.doFilter(parmsRequest, arg1); } @Override public void init(FilterConfig arg0) throws ServletException { } @Override public void destroy() { } }
添加參數(shù)過濾配置文件:
import gc.cnnvd.framework.core.filter.ParamsFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.servlet.DispatcherType; @Configuration public class ParameterTrimConfig { /** * 去除參數(shù)頭尾空格過濾器 * @return */ @Bean public FilterRegistrationBean parmsFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setDispatcherTypes(DispatcherType.REQUEST); registration.setFilter(new ParamsFilter()); registration.addUrlPatterns("/*"); registration.setName("paramsFilter"); registration.setOrder(Integer.MAX_VALUE-1); return registration; } }
處理都交給了這貨:
import com.alibaba.fastjson.JSON; import gc.cnnvd.framework.config.converter.JsonValueTrimUtil; import gc.cnnvd.framework.util.JsoupUtil; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * * @Auther linmengmeng * @Date 2021-03-25 15:47 * * Description : 請求參數(shù)的處理, * 1. 去除參數(shù)前后空格 * 2. 過濾XSS非法字符 * */ public class ParameterRequestWrapper extends HttpServletRequestWrapper { private Map<String , String[]> params = new HashMap<>(); public ParameterRequestWrapper(HttpServletRequest request) { // 將request交給父類,以便于調(diào)用對應(yīng)方法的時候,將其輸出,其實父親類的實現(xiàn)方式和第一種new的方式類似 super(request); //將參數(shù)表,賦予給當(dāng)前的Map以便于持有request中的參數(shù) Map<String, String[]> requestMap=request.getParameterMap(); this.params.putAll(requestMap); this.modifyParameterValues(); } /** * 重寫getInputStream方法 post類型的請求參數(shù)必須通過流才能獲取到值 */ @Override public ServletInputStream getInputStream() throws IOException { //非json類型,直接返回 if (!MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(super.getHeader(HttpHeaders.CONTENT_TYPE))){ return super.getInputStream(); } //為空,直接返回 String json = IOUtils.toString(super.getInputStream(), StandardCharsets.UTF_8); if (StringUtils.isEmpty(json)) { return super.getInputStream(); } Object resultObject = JsonValueTrimUtil.jsonStrTrim(json);//這里處理的是json傳參的參數(shù) ByteArrayInputStream bis = new ByteArrayInputStream(JSON.toJSONString(resultObject).getBytes(StandardCharsets.UTF_8)); return new CustomServletInputStream(bis); } /** * 將parameter的值去除空格后重寫回去 */ public void modifyParameterValues(){ Set<String> set = params.keySet(); Iterator<String> it = set.iterator(); while(it.hasNext()){ String key = it.next(); String[] values = params.get(key); values[0] = values[0].trim(); values[0] = JsoupUtil.clean(values[0]);//這里處理的是form傳參的參數(shù) params.put(key, values); } } /** * 重寫getParameter 參數(shù)從當(dāng)前類中的map獲取 */ @Override public String getParameter(String name) { String[]values = params.get(name); if(values == null || values.length == 0) { return null; } return values[0]; } /** * 重寫getParameterValues */ @Override public String[] getParameterValues(String name) {//同上 return params.get(name); } class CustomServletInputStream extends ServletInputStream{ private ByteArrayInputStream bis; public CustomServletInputStream(ByteArrayInputStream bis){ this.bis=bis; } @Override public boolean isFinished() { return true; } @Override public boolean isReady() { return true; } @Override public void setReadListener(ReadListener listener) { } @Override public int read() throws IOException { return bis.read(); } } }
上面form傳的參數(shù)直接處理了,那么要是JSON傳的參數(shù),就要借助下面的工具類了:
import cn.hutool.json.JSONTokener; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import gc.cnnvd.framework.util.JsoupUtil; import org.apache.commons.lang3.StringUtils; import java.util.Map; import java.util.Set; /** * @Auther linmengmeng * @Date 2021-03-25 15:47 * 1. 去除Json字符串中的屬性值前后空格的工具類 * 2. 去除 XSS 攻擊字符 */ public class JsonValueTrimUtil { public static Object jsonStrTrim(String jsonStr){ if (StringUtils.isBlank(jsonStr)){ return ""; } Object typeObject = new JSONTokener(jsonStr).nextValue(); if (typeObject instanceof cn.hutool.json.JSONObject){ return jsonObjectTrim(JSONObject.parseObject(jsonStr)); } if (typeObject instanceof cn.hutool.json.JSONArray){ return jsonArrayTrim(JSONArray.parseArray(jsonStr)); } jsonStr = JsoupUtil.clean(jsonStr); return jsonStr.trim(); } /** * @Description: 傳入jsonObject 去除當(dāng)中的空格 * @param jsonObject * @return */ public static JSONObject jsonObjectTrim(JSONObject jsonObject){ // 取出 jsonObject 中的字段的值的空格 Set<Map.Entry<String, Object>> entrySets = jsonObject.entrySet(); entrySets.forEach(entry -> { Object value = entry.getValue(); if (value == null){ return; } if (value instanceof String) { String resultValue = (String) value; if (StringUtils.isNotBlank(resultValue)){ resultValue = resultValue.trim(); resultValue = JsoupUtil.clean(resultValue); jsonObject.put(entry.getKey(), resultValue); } return; } if (value instanceof JSONObject){ jsonObject.put(entry.getKey(), jsonObjectTrim((JSONObject) value)); return; } if (value instanceof JSONArray){ jsonObject.put(entry.getKey(), jsonArrayTrim((JSONArray) value)); return; } }); return jsonObject; } /** * @Description: 將 jsonarry 的jsonObject 中的value值去處前后空格 * @param arr * @return */ public static JSONArray jsonArrayTrim(JSONArray arr){ if( arr != null && arr.size() > 0){ Object tempObject = null; for (int i = 0; i < arr.size(); i++) { tempObject = arr.get(i); if (tempObject instanceof String){ arr.set(i, tempObject ); continue; } JSONObject jsonObject = (JSONObject) arr.get(i); // 取出 jsonObject 中的字段的值的空格 jsonObject = jsonObjectTrim(jsonObject); arr.set(i, jsonObject ); } } return arr; } }
測試一下:
import gc.cnnvd.framework.common.api.ApiResult; import gc.cnnvd.framework.log.annotation.OperationLogIgnore; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; import lombok.Data; import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.validation.constraints.NotBlank; import java.io.Serializable; /** * @Auther linmengmeng * @Date 2021-03-30 16:24 */ @Slf4j @RestController @RequestMapping("/tourist") @Api(value = "測試游客頁面xss", tags = {"游客頁面xss"}) public class TouristTestXssController { @PostMapping("/testXssForm") @OperationLogIgnore @ApiOperation(value = "測試放開游客頁面接口xssForm", notes = "測試放開游客頁面接口xssForm", response = String.class) public ApiResult<String> testXss(TestXssFormParam testXssFormParam) { log.info("form param testStr:[{}]", testXssFormParam.getTestStr()); // from 不好使 return ApiResult.ok(testXssFormParam.getTestStr()); } @PostMapping("/testXssJson") @OperationLogIgnore @ApiOperation(value = "測試放開游客頁面接口xssJson", notes = "測試放開游客頁面接口xssJson", response = String.class) public ApiResult<String> testXssJson(@Validated @RequestBody TestXssFormParam testXssFormParam) { log.info("json param testStr:[{}]", testXssFormParam.getTestStr()); return ApiResult.ok(testXssFormParam.getTestStr()); } @Data @Accessors(chain = true) @ApiModel(value = "testXss參數(shù)") public static class TestXssFormParam implements Serializable { private static final long serialVersionUID = 1L; @NotBlank(message = "testStr不能為空") @ApiModelProperty("testStr") private String testStr; } }
上面接口里面的ApiResult為自定義封裝的返回數(shù)據(jù)格式,可以直接修改接口返回類型改為String,就是為了看下后臺處理后,返回前臺是什么樣的。
form傳參,過濾成功。
JSON傳參,也沒毛病。
到此這篇關(guān)于SpringBoot去除參數(shù)前后空格和XSS過濾的文章就介紹到這了,更多相關(guān)SpringBoot去除參數(shù)前后空格和XSS過濾內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java求兩個正整數(shù)的最大公約數(shù)和最小公倍數(shù)
這篇文章主要介紹了輸入兩個正整數(shù)m和n,求其最大公約數(shù)和最小公倍數(shù),需要的朋友可以參考下2017-02-02SpringBoot如何實現(xiàn)Tomcat自動配置
這篇文章主要介紹了SpringBoot如何實現(xiàn)Tomcat自動配置,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot框架,感興趣的朋友可以了解下2021-03-03maven插件maven-jar-plugin構(gòu)建jar文件的詳細(xì)使用
maven-jar-plugin插件時maven中最常用的插件,也是maven構(gòu)建Java程序執(zhí)行包或者依賴包的默認(rèn)插件,本文主要介紹了maven插件maven-jar-plugin構(gòu)建jar文件的詳細(xì)使用,具有一定的參考價值,感興趣的可以了解一下2024-02-02