如何使用Java防止Rest API JSON中的XSS攻击或不受信任的数据?
我开发了一个RESTAPI应用程序,并使用定制JWT处理身份验证和授权。 我希望进一步使应用程序免受XSS攻击或验证不受信任的数据,这些数据可以针对JSON请求的每个字段进行处理如何使用Java防止Rest API JSON中的XSS攻击或不受信任的数据?,java,rest,api,grails,Java,Rest,Api,Grails,我开发了一个RESTAPI应用程序,并使用定制JWT处理身份验证和授权。 我希望进一步使应用程序免受XSS攻击或验证不受信任的数据,这些数据可以针对JSON请求的每个字段进行处理 我能否在这方面获得一些帮助,以便在请求的入门级进行有效的数据处理,而不涉及内部业务验证?为此,您需要使用HTMLTILS的XSS过滤器,它将过滤任何注入的脚本并阻止您的站点。请参阅我的答案,了解其完整的代码和实现。为此,您需要使用HTMLTILS的XSS过滤器,它将过滤任何注入的脚本并阻止您的站点。请参阅我的答案,了解
我能否在这方面获得一些帮助,以便在请求的入门级进行有效的数据处理,而不涉及内部业务验证?为此,您需要使用HTMLTILS的XSS过滤器,它将过滤任何注入的脚本并阻止您的站点。请参阅我的答案,了解其完整的代码和实现。为此,您需要使用HTMLTILS的XSS过滤器,它将过滤任何注入的脚本并阻止您的站点。请参阅我的答案,了解其完整代码和实现。需要在Servlet过滤器中重写HttpServletRequest(如果您使用Servlet)
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());
ObjectMapper oMapper = new ObjectMapper();
Map <String, Object> map = oMapper.convertValue(obj, Map.class);
sanitizeRequest.setBody((new JSONObject(map)).toString().getBytes());
}
公共类XSSSanitizeFilters实现过滤器{
@凌驾
公共空间销毁(){
}
@凌驾
public void doFilter(ServletRequest arg0、ServletResponse arg1、FilterChain arg2)引发IOException、ServletException{
HttpServletRequest=(HttpServletRequest)arg0;
HttpServletResponse=(HttpServletResponse)arg1;
SanitizationRequestWrapper sanitizeRequest=新的SanitizationRequestWrapper(请求);
if(null!=sanitizeRequest.getBody()){
试一试{
sanitizeJson(sanitizeRequest);
}捕获(解析异常){
错误(“无法清理提供的JSON”);
}
arg2.doFilter(sanitizeRequest,arg1);
}否则{
arg2.doFilter(arg0,arg1);
}
}
public void init(FilterConfig FilterConfig)抛出ServletException{
}
私有void sanitizeJson(SanitizationRequestWrapper sanitizeRequest)引发IOException,ParseException{
JSONParser=新的JSONParser();
Object obj=parser.parse(sanitizeRequest.getReader());
ObjectMapper oMapper=新的ObjectMapper();
Map Map=oMapper.convertValue(obj,Map.class);
sanitizeRequest.setBody((新JSONObject(map)).toString().getBytes());
}
需要覆盖Servlet过滤器中的HttpServletRequest(如果您使用的是Servlet)
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());
ObjectMapper oMapper = new ObjectMapper();
Map <String, Object> map = oMapper.convertValue(obj, Map.class);
sanitizeRequest.setBody((new JSONObject(map)).toString().getBytes());
}
公共类XSSSanitizeFilters实现过滤器{
@凌驾
公共空间销毁(){
}
@凌驾
public void doFilter(ServletRequest arg0、ServletResponse arg1、FilterChain arg2)引发IOException、ServletException{
HttpServletRequest=(HttpServletRequest)arg0;
HttpServletResponse=(HttpServletResponse)arg1;
SanitizationRequestWrapper sanitizeRequest=新的SanitizationRequestWrapper(请求);
if(null!=sanitizeRequest.getBody()){
试一试{
sanitizeJson(sanitizeRequest);
}捕获(解析异常){
错误(“无法清理提供的JSON”);
}
arg2.doFilter(sanitizeRequest,arg1);
}否则{
arg2.doFilter(arg0,arg1);
}
}
public void init(FilterConfig FilterConfig)抛出ServletException{
}
私有void sanitizeJson(SanitizationRequestWrapper sanitizeRequest)引发IOException,ParseException{
JSONParser=新的JSONParser();
Object obj=parser.parse(sanitizeRequest.getReader());
ObjectMapper oMapper=新的ObjectMapper();
Map Map=oMapper.convertValue(obj,Map.class);
sanitizeRequest.setBody((新JSONObject(map)).toString().getBytes());
}
如果您的API不接受任何HTML字符,则可以遵循以下逻辑
您可以使用EncodeHtml清理输入负载,并将其与提供的负载进行比较
若净化的负载和提供的负载都不匹配,那个么就存在一些Html内容,直接抛出一个异常
String unsanitizedPayload = IOUtils.toString(multiReadRequest.getReader());
String sanitizedPayload = Encode.forHtmlContent(unsanitizedPayload);
if(!unsanitizedPayload.equals(sanitizedPayload)) {
throw new Exception("Improper Payload");
}
如果您的API不接受任何HTML字符,那么您可以遵循以下逻辑 您可以使用EncodeHtml清理输入负载,并将其与提供的负载进行比较 若净化的负载和提供的负载都不匹配,那个么就存在一些Html内容,直接抛出一个异常
String unsanitizedPayload = IOUtils.toString(multiReadRequest.getReader());
String sanitizedPayload = Encode.forHtmlContent(unsanitizedPayload);
if(!unsanitizedPayload.equals(sanitizedPayload)) {
throw new Exception("Improper Payload");
}
如果您使用的是Spring,Spring安全性保证了基本的XSS攻击防护级别
@SafeHtml
private String value;
您还需要添加org.jsoup依赖项。如果您使用的是Spring,Spring security可以保证基本级别的XSS攻击防护
@SafeHtml
private String value;
您还需要添加org.jsoup依赖项。此解决方案适用于将查询参数与请求头一起传递,但是我需要在JSON正文中的每个字段中为PUT或POST请求去除相同的参数。此解决方案适用于传递查询参数