Fix the code analysis error mentioned in issue #462:

(1) Append space  in string literal. (2) Guard against cross-site scripting.
pull/479/head
pandaapo 3 years ago
parent 1f4007a3f6
commit d2aff7376a

@ -115,7 +115,7 @@ public class PolarisPropertySourceAutoRefresher
LOGGER.info( LOGGER.info(
"[SCT Config] received polaris config change event and will refresh spring context." "[SCT Config] received polaris config change event and will refresh spring context."
+ "namespace = {}, group = {}, fileName = {}", + " namespace = {}, group = {}, fileName = {}",
polarisPropertySource.getNamespace(), polarisPropertySource.getNamespace(),
polarisPropertySource.getGroup(), polarisPropertySource.getGroup(),
polarisPropertySource.getFileName()); polarisPropertySource.getFileName());

@ -0,0 +1,57 @@
package com.tencent.cloud.polaris.circuitbreaker.example.xss;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Escape String in ResponseBody before write it into HttpResponse
*
* @author Daifu Wu
*/
@ControllerAdvice
public class XssResponseBodyAdvice implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter methodParameter, Class aClass) {
return methodParameter.hasMethodAnnotation(ResponseBody.class) || methodParameter.getDeclaringClass().getAnnotation(ResponseBody.class) != null || methodParameter.getDeclaringClass().getAnnotation(RestController.class) != null;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if (body instanceof String) {
body = StringEscapeUtils.escapeHtml((String)body);
return body;
}
try {
if (!((Class)body.getClass().getField("TYPE").get(null)).isPrimitive()) {
Map<String, Object> map = new HashMap<>();
Field[] fields = body.getClass().getDeclaredFields();
for (Field field: fields) {
field.setAccessible(true);
Object value = field.get(body);
if (value instanceof String) {
value = StringEscapeUtils.escapeHtml((String) value);
}
map.put(field.getName(), value);
}
return map;
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
return body;
}
}

@ -0,0 +1,23 @@
package com.tencent.cloud.polaris.gateway.example.callee.xss;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* filter request aim at defending against XSS
*
* @author Daifu Wu
*/
@WebFilter(urlPatterns = "/*", filterName = "xssFilter")
@Component
public class XssFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) servletRequest), servletResponse);
}
}

@ -0,0 +1,173 @@
package com.tencent.cloud.polaris.gateway.example.callee.xss;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.web.servlet.HandlerMapping;
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;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Wrap HttpServletRequest to escape String arguments
*
* @author Daifu Wu
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] requestBody;
public XssHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
BufferedReader reader = request.getReader();
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
if (stringBuilder.length() > 0) {
String json = stringBuilder.toString();
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.readValue(json, Map.class);
map.forEach((k, v) -> {
if (v instanceof String) {
v = cleanXSS((String) v);
map.put(k, v);
}
});
json = objectMapper.writeValueAsString(map);
requestBody = json.getBytes();
}
}
/**
* Handles arguments annotated by @RequestBody
*
* @return
* @throws IOException
*/
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
}
/**
* Handles arguments annotated by @RequestParam
*
* @param name
* @return
*/
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values != null && values.length > 0) {
String[] safeValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
safeValues[i] = cleanXSS(values[i]);
}
return safeValues;
}
return values;
}
/**
* Handles arguments annotated by @PathVariable
*
* @param name
* @return
*/
@Override
public Object getAttribute(String name) {
Object value = super.getAttribute(name);
if (name.equalsIgnoreCase(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE) && value != null && value instanceof Map) {
((Map) value).forEach((k, v) -> {
if (v instanceof String) {
v = cleanXSS((String) v);
((Map) value).put(k, v);
}
});
}
return value;
}
/**
* Handles arguments annotated by @RequestHeader
*
* @param name
* @return
*/
@Override
public Enumeration<String> getHeaders(String name) {
List<String> list = Collections.list(super.getHeaders(name));
list = list.stream().map((e) -> {
ObjectMapper objectMapper = new ObjectMapper();
try {
Map<String, String> map = objectMapper.readValue(e, Map.class);
map.forEach((k, v) -> {
v = cleanXSS(v);
map.put(k, v);
});
e = objectMapper.writeValueAsString(map);
} catch (JsonProcessingException e1) {
e1.printStackTrace();
}
return e;
}).collect(Collectors.toList());
return Collections.enumeration(list);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value != null) {
value = cleanXSS(value);
}
return value;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
/**
* Escape string to defend against XSS
*
* @param value
*/
private String cleanXSS(String value) {
value = StringEscapeUtils.escapeHtml(value);
return value;
}
}

@ -0,0 +1,23 @@
package com.tencent.cloud.polaris.gateway.example.callee.xss;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* filter request aim at defending against XSS
*
* @author Daifu Wu
*/
@WebFilter(urlPatterns = "/*", filterName = "xssFilter")
@Component
public class XssFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) servletRequest), servletResponse);
}
}

@ -0,0 +1,171 @@
package com.tencent.cloud.polaris.gateway.example.callee.xss;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.web.servlet.HandlerMapping;
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;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Wrap HttpServletRequest to escape String arguments
*
* @author Daifu Wu
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] requestBody;
public XssHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
BufferedReader reader = request.getReader();
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
if (stringBuilder.length() > 0) {
String json = stringBuilder.toString();
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.readValue(json, Map.class);
map.forEach((k, v) -> {
if (v instanceof String) {
v = cleanXSS((String) v);
map.put(k, v);
}
});
json = objectMapper.writeValueAsString(map);
requestBody = json.getBytes();
}
}
/**
* Handles arguments annotated by @RequestBody
*
* @return
* @throws IOException
*/
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
}
/**
* Handles arguments annotated by @RequestParam
*
* @param name
* @return
*/
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values != null && values.length > 0) {
String[] safeValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
safeValues[i] = cleanXSS(values[i]);
}
return safeValues;
}
return values;
}
/**
* Handles arguments annotated by @PathVariable
*
* @param name
* @return
*/
@Override
public Object getAttribute(String name) {
Object value = super.getAttribute(name);
if (name.equalsIgnoreCase(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE) && value != null && value instanceof Map) {
((Map) value).forEach((k, v) -> {
if (v instanceof String) {
v = cleanXSS((String) v);
((Map) value).put(k, v);
}
});
}
return value;
}
/**
* Handles arguments annotated by @RequestHeader
*
* @param name
* @return
*/
@Override
public Enumeration<String> getHeaders(String name) {
List<String> list = Collections.list(super.getHeaders(name));
list = list.stream().map((e) -> {
ObjectMapper objectMapper = new ObjectMapper();
try {
Map<String, String> map = objectMapper.readValue(e, Map.class);
map.forEach((k, v) -> {
v = cleanXSS(v);
map.put(k, v);
});
e = objectMapper.writeValueAsString(map);
} catch (JsonProcessingException e1) {
e1.printStackTrace();
}
return e;
}).collect(Collectors.toList());
return Collections.enumeration(list);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value != null) {
value = cleanXSS(value);
}
return value;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
/**
* Escape string to defend against XSS
*
* @param value
*/
private String cleanXSS(String value) {
value = StringEscapeUtils.escapeHtml(value);
return value;
}
}

@ -0,0 +1,23 @@
package com.tencent.cloud.polaris.router.example.xss;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* filter request aim at defending against XSS
*
* @author Daifu Wu
*/
@WebFilter(urlPatterns = "/*", filterName = "xssFilter")
@Component
public class XssFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) servletRequest), servletResponse);
}
}

@ -0,0 +1,144 @@
package com.tencent.cloud.polaris.router.example.xss;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.util.HtmlUtils;
import org.springframework.web.util.JavaScriptUtils;
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;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
/**
* Wrap HttpServletRequest to escape String arguments
*
* @author Daifu Wu
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] requestBody;
public XssHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
BufferedReader reader = request.getReader();
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
String json = stringBuilder.toString();
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.readValue(json, Map.class);
map.forEach((k, v) -> {
if (v instanceof String) {
v = cleanXSS((String) v);
map.put(k, v);
}
});
json = objectMapper.writeValueAsString(map);
requestBody = json.getBytes();
}
/**
* Handles arguments annotated by @RequestBody
*
* @return
* @throws IOException
*/
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
}
/**
* Handles arguments annotated by @RequestParam
*
* @param name
* @return
*/
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values != null && values.length > 0) {
String[] safeValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
safeValues[i] = cleanXSS(values[i]);
}
return safeValues;
}
return values;
}
/**
* Handles arguments annotated by @PathVariable
*
* @param name
* @return
*/
@Override
public Object getAttribute(String name) {
Object value = super.getAttribute(name);
if (name.equalsIgnoreCase(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE) && value != null && value instanceof Map) {
((Map) value).forEach((k, v) -> {
if (v instanceof String) {
v = cleanXSS((String) v);
((Map) value).put(k, v);
}
});
}
return value;
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value != null) {
value = cleanXSS(value);
}
return value;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
/**
* Escape string to defend against XSS
*
* @param value
*/
private String cleanXSS(String value) {
value = StringEscapeUtils.escapeHtml(value);
return value;
}
}

@ -0,0 +1,23 @@
package com.tencent.cloud.polaris.router.example.xss;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* filter request aim at defending against XSS
*
* @author Daifu Wu
*/
@WebFilter(urlPatterns = "/*", filterName = "xssFilter")
@Component
public class XssFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) servletRequest), servletResponse);
}
}

@ -0,0 +1,140 @@
package com.tencent.cloud.polaris.router.example.xss;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.web.servlet.HandlerMapping;
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;
import java.util.Map;
/**
* Wrap HttpServletRequest to escape String arguments
*
* @author Daifu Wu
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] requestBody;
public XssHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
BufferedReader reader = request.getReader();
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
String json = stringBuilder.toString();
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.readValue(json, Map.class);
map.forEach((k, v) -> {
if (v instanceof String) {
v = cleanXSS((String) v);
map.put(k, v);
}
});
json = objectMapper.writeValueAsString(map);
requestBody = json.getBytes();
}
/**
* Handles arguments annotated by @RequestBody
*
* @return
* @throws IOException
*/
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
}
/**
* Handles arguments annotated by @RequestParam
*
* @param name
* @return
*/
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values != null && values.length > 0) {
String[] safeValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
safeValues[i] = cleanXSS(values[i]);
}
return safeValues;
}
return values;
}
/**
* Handles arguments annotated by @PathVariable
*
* @param name
* @return
*/
@Override
public Object getAttribute(String name) {
Object value = super.getAttribute(name);
if (name.equalsIgnoreCase(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE) && value != null && value instanceof Map) {
((Map) value).forEach((k, v) -> {
if (v instanceof String) {
v = cleanXSS((String) v);
((Map) value).put(k, v);
}
});
}
return value;
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value != null) {
value = cleanXSS(value);
}
return value;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
/**
* Escape string to defend against XSS
*
* @param value
*/
private String cleanXSS(String value) {
value = StringEscapeUtils.escapeHtml(value);
return value;
}
}
Loading…
Cancel
Save