diff --git a/im-platform/src/main/java/com/bx/implatform/config/MvcConfig.java b/im-platform/src/main/java/com/bx/implatform/config/MvcConfig.java index 71561d2..32a3777 100644 --- a/im-platform/src/main/java/com/bx/implatform/config/MvcConfig.java +++ b/im-platform/src/main/java/com/bx/implatform/config/MvcConfig.java @@ -1,6 +1,7 @@ package com.bx.implatform.config; import com.bx.implatform.interceptor.AuthInterceptor; +import com.bx.implatform.interceptor.XssInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -15,18 +16,25 @@ public class MvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(XssInterceptor()) + .addPathPatterns("/**"); registry.addInterceptor(authInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/login","/logout","/register","/refreshToken", "/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"); } - @Bean public AuthInterceptor authInterceptor() { return new AuthInterceptor(); } + @Bean + public XssInterceptor XssInterceptor() { + return new XssInterceptor(); + } + + @Bean public PasswordEncoder passwordEncoder(){ // 使用BCrypt加密密码 diff --git a/im-platform/src/main/java/com/bx/implatform/enums/ResultCode.java b/im-platform/src/main/java/com/bx/implatform/enums/ResultCode.java index 74981f6..dc5cb40 100644 --- a/im-platform/src/main/java/com/bx/implatform/enums/ResultCode.java +++ b/im-platform/src/main/java/com/bx/implatform/enums/ResultCode.java @@ -14,6 +14,7 @@ public enum ResultCode { PROGRAM_ERROR(500,"系统繁忙,请稍后再试"), PASSWOR_ERROR(10001,"密码不正确"), USERNAME_ALREADY_REGISTER(10003,"该用户名已注册"), + XSS_PARAM_ERROR(10004,"请不要输入非法内容"), ; diff --git a/im-platform/src/main/java/com/bx/implatform/filter/CacheFilter.java b/im-platform/src/main/java/com/bx/implatform/filter/CacheFilter.java new file mode 100644 index 0000000..9353e0f --- /dev/null +++ b/im-platform/src/main/java/com/bx/implatform/filter/CacheFilter.java @@ -0,0 +1,28 @@ +package com.bx.implatform.filter; + +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.stereotype.Component; + +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.List; + +@Component +@ServletComponentScan +@WebFilter(urlPatterns = "/*",filterName = "xssFilter") +public class CacheFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) {} + + @Override + public void destroy() {} + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + chain.doFilter(new CacheHttpServletRequestWrapper((HttpServletRequest) request), response); + } + +} \ No newline at end of file diff --git a/im-platform/src/main/java/com/bx/implatform/filter/CacheHttpServletRequestWrapper.java b/im-platform/src/main/java/com/bx/implatform/filter/CacheHttpServletRequestWrapper.java new file mode 100644 index 0000000..761c743 --- /dev/null +++ b/im-platform/src/main/java/com/bx/implatform/filter/CacheHttpServletRequestWrapper.java @@ -0,0 +1,61 @@ +package com.bx.implatform.filter; + +import org.apache.commons.compress.utils.IOUtils; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.*; + +public class CacheHttpServletRequestWrapper extends HttpServletRequestWrapper { + private byte[] requestBody; + private HttpServletRequest request; + + public CacheHttpServletRequestWrapper(HttpServletRequest request) throws IOException { + super(request); + this.request = request; + } + + + @Override + public ServletInputStream getInputStream() throws IOException { + if (null == this.requestBody) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + IOUtils.copy(request.getInputStream(), baos); + this.requestBody = baos.toByteArray(); + } + ByteArrayInputStream bais = new ByteArrayInputStream(requestBody); + return new ServletInputStream() { + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener listener) { + } + + @Override + public int read() { + return bais.read(); + } + }; + } + + public byte[] getRequestBody() { + return requestBody; + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(this.getInputStream())); + } + + +} diff --git a/im-platform/src/main/java/com/bx/implatform/interceptor/XssInterceptor.java b/im-platform/src/main/java/com/bx/implatform/interceptor/XssInterceptor.java new file mode 100644 index 0000000..fd384e1 --- /dev/null +++ b/im-platform/src/main/java/com/bx/implatform/interceptor/XssInterceptor.java @@ -0,0 +1,48 @@ +package com.bx.implatform.interceptor; + +import com.bx.implatform.enums.ResultCode; +import com.bx.implatform.exception.GlobalException; +import com.bx.implatform.util.XssUtil; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.util.Map; + +@Slf4j +public class XssInterceptor implements HandlerInterceptor { + + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + // 检查参数 + Map paramMap = request.getParameterMap(); + for(String[] values:paramMap.values()){ + for(String value:values){ + if(XssUtil.checkXss(value)){ + throw new GlobalException(ResultCode.XSS_PARAM_ERROR); + } + } + } + // 检查body + String body = getBody(request); + if(XssUtil.checkXss(body)){ + throw new GlobalException(ResultCode.XSS_PARAM_ERROR); + } + return true; + } + + @SneakyThrows + private String getBody(HttpServletRequest request){ + BufferedReader reader = request.getReader(); + StringBuilder stringBuilder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + stringBuilder.append(line); + } + return stringBuilder.toString(); + } +} diff --git a/im-platform/src/main/java/com/bx/implatform/util/XssUtil.java b/im-platform/src/main/java/com/bx/implatform/util/XssUtil.java new file mode 100644 index 0000000..15461a3 --- /dev/null +++ b/im-platform/src/main/java/com/bx/implatform/util/XssUtil.java @@ -0,0 +1,20 @@ +package com.bx.implatform.util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class XssUtil { + + private static final String XSS_PATTERN = "((?i))|((?i)alert\\s*\\()|((?i)prompt\\s*\\()|((?i)document\\.cookie)|((?i)location\\.href)|((?i)window\\.location)|((?i)onerror\\s*\\()|((?i)eval\\s*\\()|((?i)window\\.open\\s*\\()|((?i)innerHTML)|((?i)onclick\\s*\\()|((?i)onmouseover\\s*\\()|((?i)onsubmit\\s*\\()|((?i)onload\\s*\\()|((?i)onfocus\\s*\\()|((?i)onblur\\s*\\()|((?i)onkeyup\\s*\\()|((?i)onkeydown\\s*\\()|((?i)onkeypress\\s*\\()|((?i)onmouseout\\s*\\()|((?i)src=)|((?i)href=)|((?i)style=)|((?i)background=)|((?i)expression\\s*\\()|((?i)XMLHttpRequest\\s*\\()|((?i)ActiveXObject\\s*\\()|((?i)iframe)|((?i)document\\.write\\s*\\()|((?i)document\\.writeln\\s*\\()|((?i)setTimeout\\s*\\()|((?i)setInterval\\s*\\()|((?i)onreadystatechange\\s*\\()|((?i)appendChild\\s*\\()|((?i)createTextNode\\s*\\()|((?i)createElement\\s*\\()|((?i)getElementsByTagName\\s*\\()|((?i)getElementsByClassName\\s*\\()|((?i)querySelector\\s*\\()|((?i)querySelectorAll\\s*\\()|((?i)document\\.location)|((?i)document\\.body\\.innerHTML)|((?i)document\\.forms)|((?i)document\\.images)|((?i)document\\.links)|((?i)document\\.URL)|((?i)document\\.domain)|((?i)document\\.referrer)|((?i)history\\.back\\s*\\()"; + private static final Pattern PATTERN = Pattern.compile(XSS_PATTERN); + + public static boolean checkXss(String inputString) { + if (inputString!=null) { + Matcher matcher = PATTERN.matcher(inputString); + if (matcher.find()) { + return true; + } + } + return false; + } +}