如何使用Java防止Rest API JSON中的XSS攻击或不受信任的数据? [英] How to prevent XSS attacks or untrusted data in Rest API JSON using Java?
问题描述
我已经开发了Rest API应用程序,并使用自定义JWT处理了身份验证和授权. 我想进一步提高应用程序的安全性,使其免受XSS攻击或对不受信任数据的验证,这些数据可以针对JSON请求的每个字段进行处理.
I had developed a Rest API application and have handled Authentication and Authorization using custom JWT. I want to further make the application secure from XSS attacks or validation for untrusted data which could be handled for each and every field of JSON request.
我可以在这方面获得一些帮助,以便在请求的入门级进行有效的数据处理,而无需进行内部业务验证吗?
Can I get some help in this regard so that efficient data processing will happen at the entry-level of the request without touching internal business validation?
推荐答案
需要覆盖Servlet过滤器中的HttpServletRequest(如果使用的是Servlet).
Need to override the HttpServletRequest in a Servlet Filter(if you are using Servlet).
-
扩展了存储JSON正文的HttpServletRequestWrapper(目的是清理JSON正文).
Extends HttpServletRequestWrapper that stores JSON body(intention is to sanitize JSON body).
剥离/转义符合条件的JSON值
Strip/ escape the eligible JSON value
扩展了"HttpServletRequestWrapper" :
public class SanitizationRequestWrapper extends HttpServletRequestWrapper {
public byte[] getBody() {
return body;
}
public void setBody(byte[] body) {
this.body = body;
}
private byte[] body;
public SanitizationRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
try {
body = IOUtils.toByteArray(super.getInputStream());
}catch (NullPointerException e){
}
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStreamImpl(new ByteArrayInputStream(body));
}
@Override
public BufferedReader getReader() throws IOException {
String enc = getCharacterEncoding();
if (enc == null) enc = "UTF-8";
return new BufferedReader(new InputStreamReader(getInputStream(), enc));
}
private class ServletInputStreamImpl extends ServletInputStream {
private InputStream is;
public ServletInputStreamImpl(InputStream is) {
this.is = is;
}
public int read() throws IOException {
return is.read();
}
public boolean markSupported() {
return false;
}
public synchronized void mark(int i) {
throw new RuntimeException(new IOException("mark/reset not supported"));
}
public synchronized void reset() throws IOException {
throw new IOException("mark/reset not supported");
}
}
}
用于过滤请求正文的Servlet过滤器:
public class XSSSanitizeFilters implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) arg0;
HttpServletResponse response = (HttpServletResponse) arg1;
SanitizationRequestWrapper sanitizeRequest = new SanitizationRequestWrapper(request);
if (null != sanitizeRequest.getBody()) {
try {
sanitizeJson(sanitizeRequest);
} catch (ParseException e) {
LOG.error("Unable to Sanitize the provided JSON .");
}
arg2.doFilter(sanitizeRequest, arg1);
} else {
arg2.doFilter(arg0, arg1);
}
}
public void init(FilterConfig filterConfig) throws ServletException {
}
private void sanitizeJson(SanitizationRequestWrapper sanitizeRequest ) throws IOException, ParseException {
JSONParser parser= new JSONParser();
Object obj = parser.parse(sanitizeRequest.getReader());
Map <String, Object> map = convertToMap((JSONObject)obj);
sanitizeRequest.setBody((new JSONObject(map)).toString().getBytes());
}
public Map<String, Object> convertToMap(JSONObject jsonObject) {
Map<String, Object> map = new HashMap<>();
List<Object> mapArr = null;
for (Object key : jsonObject.keySet()) {
if (jsonObject.get(key) instanceof JSONObject) {
map.put((String) key, convertToMap((JSONObject) jsonObject.get(key)));
} else if (jsonObject.get(key) instanceof JSONArray) {
mapArr = new ArrayList<Object>();
JSONArray jArray = (JSONArray) jsonObject.get(key);
for (int i = 0; i < jArray.size(); i++) {
if (jArray.get(i) instanceof JSONObject || jArray.get(i) instanceof JSONArray) {
mapArr.add(convertToMap((JSONObject) jArray.get(i)));
} else {
mapArr.add(jArray.get(i));
}
}
map.put((String) key, mapArr);
} else {
// map.put((String) key, XssSanitizerUtil.stripXSS(jsonObject.get(key).toString()));
map.put((String) key, StringEscapeUtils.escapeHtml(jsonObject.get(key).toString()));
}
}
return map;
}
}
这篇关于如何使用Java防止Rest API JSON中的XSS攻击或不受信任的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!