Java 使用JAX-RS解决AngularJSON漏洞(RESTEasy)

Java 使用JAX-RS解决AngularJSON漏洞(RESTEasy),java,angularjs,jax-rs,resteasy,Java,Angularjs,Jax Rs,Resteasy,我正试图实现JSON漏洞保护下描述的解决方法。解决方法是让服务器在每个JSON请求前加上字符串“)]}”,即\n” 我的服务器是一个运行RESTEasy web服务的JBoss。我尝试使用JAX-RS过滤器和拦截器来实现解决方案,但没有成功 甚至可以在RESTEasy的每个JSON响应前面加上一个字符串,而不修改所有POJO吗 您可以自己实现自定义POJO并序列化POJO @Provider @Produces(MediaType.APPLICATION_JSON) public class J

我正试图实现JSON漏洞保护下描述的解决方法。解决方法是让服务器在每个JSON请求前加上字符串“
)]}”,即\n

我的服务器是一个运行RESTEasy web服务的JBoss。我尝试使用JAX-RS过滤器和拦截器来实现解决方案,但没有成功


甚至可以在RESTEasy的每个JSON响应前面加上一个字符串,而不修改所有POJO吗

您可以自己实现自定义POJO并序列化POJO

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JsonVulnerabilityWriter implements MessageBodyWriter<Object> {

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return true;
    }

    @Override
    public long getSize(Object t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

    @Override
    public void writeTo(Object obj, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
        MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
        entityStream.write(")]}',\n".getBytes("UTF-8"));
        entityStream.write(new ObjectMapper().writeValueAsBytes(obj));
    }

}
@Provider
@产生(MediaType.APPLICATION_JSON)
公共类JsonVulnerabilityWriter实现MessageBodyWriter{
@凌驾
公共布尔值可写(类类型、类型genericType、注释[]注释、MediaType MediaType){
返回true;
}
@凌驾
公共长getSize(对象t、类类型、类型genericType、注释[]注释、MediaType MediaType){
返回-1;
}
@凌驾
public void writeTo(对象对象对象、类类型、类型genericType、注释[]注释、MediaType MediaType、,
多值Map httpHeaders,OutputStream entityStream)引发IOException,WebApplicationException{
entityStream.write(“)]}',\n.getBytes(“UTF-8”);
write(新的ObjectMapper().writeValueAsBytes(obj));
}
}

我实现了一个服务器拦截器,因此可以使用现有的序列化:

import org.jboss.resteasy.annotations.interception.ServerInterceptor;
import org.jboss.resteasy.spi.interception.MessageBodyWriterContext;
import org.jboss.resteasy.spi.interception.MessageBodyWriterInterceptor;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.util.Objects;

@Provider
@ServerInterceptor
public class AngularJsonVulnerabilityProtectionInterceptor implements MessageBodyWriterInterceptor {

  @Override
  public void write(MessageBodyWriterContext context) throws IOException, WebApplicationException {
    if (MediaType.APPLICATION_JSON.equals(Objects.toString(context.getMediaType()))) {
      context.getOutputStream().write(")]}',\n".getBytes("UTF-8"));
    }
    context.proceed();
  }
}

通过google和改进的解决方案找到该线程,因此它不需要任何resteasy特定的类。这应该适用于普通JavaEE/JAX-RS

import java.io.IOException;
import java.util.Objects;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;

/**
 * Responsefilter that prefixes all JSON responses with ")]}',\n" for security reasons.
 * 
 * @see https://docs.angularjs.org/api/ng/service/$http "JSON Vulnerability"
 */
@Provider
public class AngularJsonVulnerabilityProtectionInterceptor implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
            throws IOException {
        boolean mediaTypeJSON = MediaType.APPLICATION_JSON.equals(Objects.toString(responseContext.getMediaType()));
        if (mediaTypeJSON) {
            responseContext.getEntityStream().write(")]}',\n".getBytes("UTF-8"));
        }
    }
}
我无法得到Glassfish的工作答案,因为Glassfish报告如下:

java.lang.IllegalStateException:未定义流提供程序。信息技术 必须在将第一个字节写入实体输出流之前设置

相反,我也重写了他的答案,但使用了:


我要补充的是,由于我在默认的Jackson JSON编写器中使用RESTEasy,所以最好使用ObjectMapper而不是gson—例如:entityStream.write(new ObjectMapper().writeValueAsBytes(obj));说得好!我会更新我的答案。您也可以像这样扩展
JacksonJsonProvider
ResteasyJacksonProvider
,但这在wildfly上对我不起作用。
import java.io.IOException;
import java.util.Objects;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;

@Provider
public class AngularJsonInterceptor implements WriterInterceptor {

    @Override
    public void aroundWriteTo(WriterInterceptorContext context)
                    throws IOException, WebApplicationException {

        if (MediaType.APPLICATION_JSON.equals(Objects.toString(context.getMediaType()))) {
            context.getOutputStream().write(")]}',\n".getBytes("UTF-8"));
        }
        context.proceed();
    }
}