8 changed files with 141 additions and 97 deletions
@ -1,47 +0,0 @@ |
|||
package com.bx.implatform.config; |
|||
|
|||
import com.fasterxml.jackson.core.JsonParser; |
|||
import com.fasterxml.jackson.databind.DeserializationContext; |
|||
import com.fasterxml.jackson.databind.JsonDeserializer; |
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import com.fasterxml.jackson.databind.module.SimpleModule; |
|||
import org.apache.commons.lang3.StringEscapeUtils; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Configuration; |
|||
|
|||
import javax.annotation.PostConstruct; |
|||
import java.io.IOException; |
|||
|
|||
@Configuration |
|||
public class XssBodyConfig { |
|||
|
|||
@Autowired |
|||
private ObjectMapper objectMapper; |
|||
|
|||
@PostConstruct |
|||
public void afterPropertiesSet() throws Exception { |
|||
SimpleModule simpleModule = new SimpleModule(); |
|||
simpleModule.addDeserializer(String.class, new JsonHtmlXssDeserializer()); |
|||
objectMapper.registerModule(simpleModule); |
|||
} |
|||
|
|||
|
|||
class JsonHtmlXssDeserializer extends JsonDeserializer { |
|||
|
|||
@Override |
|||
public Class<String> handledType() { |
|||
return String.class; |
|||
} |
|||
|
|||
@Override |
|||
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { |
|||
String value = jsonParser.getValueAsString(); |
|||
if (StringUtils.isNotEmpty(value)) { |
|||
return StringEscapeUtils.escapeHtml4(value); |
|||
} |
|||
return value; |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -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())); |
|||
} |
|||
|
|||
|
|||
} |
|||
@ -1,47 +0,0 @@ |
|||
package com.bx.implatform.filter; |
|||
|
|||
import cn.hutool.extra.servlet.ServletUtil; |
|||
import lombok.SneakyThrows; |
|||
import org.apache.commons.lang3.ArrayUtils; |
|||
import org.apache.commons.lang3.StringEscapeUtils; |
|||
import org.springframework.web.util.HtmlUtils; |
|||
|
|||
import javax.servlet.ReadListener; |
|||
import javax.servlet.ServletInputStream; |
|||
import javax.servlet.http.HttpServletRequest; |
|||
import javax.servlet.http.HttpServletRequestWrapper; |
|||
import java.io.BufferedReader; |
|||
import java.io.ByteArrayInputStream; |
|||
import java.io.IOException; |
|||
import java.io.InputStreamReader; |
|||
|
|||
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { |
|||
|
|||
public XssHttpServletRequestWrapper(HttpServletRequest request) { |
|||
super(request); |
|||
} |
|||
|
|||
@Override |
|||
public String getQueryString() { |
|||
return StringEscapeUtils.escapeHtml4(super.getQueryString()); |
|||
} |
|||
|
|||
@Override |
|||
public String getParameter(String name) { |
|||
return StringEscapeUtils.escapeHtml4(super.getParameter(name)); |
|||
} |
|||
|
|||
@Override |
|||
public String[] getParameterValues(String name) { |
|||
String[] values = super.getParameterValues(name); |
|||
if (ArrayUtils.isEmpty(values)) { |
|||
return values; |
|||
} |
|||
int length = values.length; |
|||
String[] escapeValues = new String[length]; |
|||
for (int i = 0; i < length; i++) { |
|||
escapeValues[i] = StringEscapeUtils.escapeHtml4(values[i]); |
|||
} |
|||
return escapeValues; |
|||
} |
|||
} |
|||
@ -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<String, String[]> 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(); |
|||
} |
|||
} |
|||
@ -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)<script.*?>)|((?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; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue