Entity provider
selection confusion
attacks in JAX-RS
applications
Mikhail Egorov
β€’ Security researcher, bug hunter
β€’ Application security engineer at Odin [ Ingram Micro Cloud ]
β€’ @0ang3el
β€’ http://0ang3el.blogspot.com
β€’ http://www.slideshare.net/0ang3el
About me
β€’ Java API for creating RESTful web services
β€’ Part of J2EE since J2EE 6
β€’ JAX-RS 2.0 [ https://jcp.org/aboutJava/communityprocess/final/jsr339/index.html ]
β€’ RESTEasy [ Red Hat ] , Jersey [ Oracle ]
What is JAX-RS?
β€’ RESTful web services are based on REST architectural style
β€’ Some features
β€’ Resource identification through URI
β€’ Uniform interface
β€’ Self-descriptive messages
β€’ Stateful interactions through hyperlinks
What is RESTful web services?
Simple RESTful web service built w/ JAX-RS
;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path("helloworld")
public class HelloWorldResource {
public static final String CLICHED_MESSAGE = "Hello World!";
@GET
@Produces("text/plain")
public String getHello() {
return CLICHED_MESSAGE;
}
}
Simple RESTful web service built w/ JAX-RS
;
β€’ Annotated parameters
β€’ @PathParam
β€’ @QueryParam
β€’ @FormParam
β€’ @HeaderParam
β€’ @CookieParam
β€’ @MatrixParam
β€’ Entity parameters – parameters without annotation
Passing parameters to resource method
β€’ @QueryParam example
β€’ Entity parameter example
Passing parameters to resource method
@GET
@Path("/order")
public String getOrder(@QueryParam("id") Sting id) {
...
}
@Path("/order")
@PUT
public void putOrder(Order order) {
...
}
β€’ Unmarshalling – process of converting message content into Java
object which is passed as parameter into resource method
β€’ Entity providers are used for marshalling/unmarshalling
Entity parameters
β€’ Entity providers – specials Java classes
β€’ Annotated with @Provider
β€’ Implement javax.ws.rs.ext.MessageBodyReader [ isReadable(), readFrom() ]
β€’ Entity provider is selected based on
β€’ Content type specified with @Consumes annotation
β€’ Content-Type HTTP header in request
β€’ Java Class of entity parameter
β€’ There are interesting built-in entity providers
Entity providers
β€’ Jersey performs WEB-INF/lib scanning for entity providers
β€’ RESTEasy by default performs WEB-INF/lib scanning for entity
providers, parameter resteasy.scan.providers does not work
[ https://issues.jboss.org/browse/RESTEASY-1504 ]
Automated scanning for entity providers
β€’ Attacker selects entity provider which is not intended for
unmarshalling, by manipulating with Content-Type header of HTTP
request
Entity provider selection confusion attack
β€’ Occur when resource or resource method does not specify preferred
content type via @Consumes annotation
β€’ Or specifies it too permissive
β€’ */*
β€’ application/*
β€’ And in some cases when content type is
β€’ multipart/*
β€’ multipart/form-data
β€’ etc
Entity provider selection confusion attack
β€’ Impact of attack
β€’ RCE
β€’ DoS
β€’ CSRF
β€’ XXE
β€’ etc
Entity provider selection confusion attack
β€’ RESTEasy by default has SerializableProvider entity provider
β€’ Vulnerable resource method doConcat()
Attack for RESTEasy [ CVE-2016-7050 ]
@POST
@Path("/concat")
@Produces(MediaType.APPLICATION_JSON)
public Map doConcat(Pair pair) {
HashMap result = new HashMap();
result.put("Result", pair.getP1() + pair.getP2());
return result;
}
public class Pair implements Serializable {
...
}
β€’ isReadable() method of SerializableProvider
β€’ SerializableProvider is used when Content-Type is application/x-java-
serialized-object and Java class of entity parameter is serializable
Attack for RESTEasy [ CVE-2016-7050 ]
public boolean isReadable(Class type, Type genericType, Annotation[] annotations,
MediaType mediaType) {
return (Serializable.class.isAssignableFrom(type)) &&
(APPLICATION_SERIALIZABLE_TYPE.getType().equals(mediaType.getType())) &&
(APPLICATION_SERIALIZABLE_TYPE.getSubtype().equals(mediaType.getSubtype()));
}
β€’ readFrom() method of SerializableProvider
Attack for RESTEasy [ CVE-2016-7050 ]
public Serializable readFrom(Class type, Type genericType, Annotation[]
annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream
entityStream) throws IOException, WebApplicationException {
BufferedInputStream bis = new BufferedInputStream(entityStream);
ObjectInputStream ois = new ObjectInputStream(bis);
try {
return (Serializable)Serializable.class.cast(ois.readObject());
} catch (ClassNotFoundException e) {
throw new WebApplicationException(e);
}
}
Attack for RESTEasy [ CVE-2016-7050 ]
Attack for RESTEasy [ CVE-2016-7050 ]
β€’ Jersey has default jersey-media-kryo entity provider
β€’ Vulnerable resource method doShowSize()
Attack for Jersey
@POST
@Path("/size")
@Produces(MediaType.APPLICATION_JSON)
public Map<String, String> doShowSize(ArrayList<Pair> pairs) {
HashMap<String, String> result = new HashMap<String, String>();
result.put("Count", String.valueOf(pairs.size()));
return result;
}
β€’ DoS payload - https://gist.github.com/coekie/a27cc406fc9f3dc7a70d
Attack for Jersey
β€’ DoS payload - https://gist.github.com/coekie/a27cc406fc9f3dc7a70d
Attack for Jersey
β€’ Narrow possible content types for resource or resource method using
@Consumes annotation
β€’ Use multipart/*, multipart/form-data, etc. content types with caution
β€’ Java deserialization bugs exist not only in RMI/JMX/JMS
Takeaways

Entity provider selection confusion attacks in JAX-RS applications

  • 1.
    Entity provider selection confusion attacksin JAX-RS applications Mikhail Egorov
  • 2.
    β€’ Security researcher,bug hunter β€’ Application security engineer at Odin [ Ingram Micro Cloud ] β€’ @0ang3el β€’ http://0ang3el.blogspot.com β€’ http://www.slideshare.net/0ang3el About me
  • 3.
    β€’ Java APIfor creating RESTful web services β€’ Part of J2EE since J2EE 6 β€’ JAX-RS 2.0 [ https://jcp.org/aboutJava/communityprocess/final/jsr339/index.html ] β€’ RESTEasy [ Red Hat ] , Jersey [ Oracle ] What is JAX-RS?
  • 4.
    β€’ RESTful webservices are based on REST architectural style β€’ Some features β€’ Resource identification through URI β€’ Uniform interface β€’ Self-descriptive messages β€’ Stateful interactions through hyperlinks What is RESTful web services?
  • 5.
    Simple RESTful webservice built w/ JAX-RS ; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; @Path("helloworld") public class HelloWorldResource { public static final String CLICHED_MESSAGE = "Hello World!"; @GET @Produces("text/plain") public String getHello() { return CLICHED_MESSAGE; } }
  • 6.
    Simple RESTful webservice built w/ JAX-RS ;
  • 7.
    β€’ Annotated parameters β€’@PathParam β€’ @QueryParam β€’ @FormParam β€’ @HeaderParam β€’ @CookieParam β€’ @MatrixParam β€’ Entity parameters – parameters without annotation Passing parameters to resource method
  • 8.
    β€’ @QueryParam example β€’Entity parameter example Passing parameters to resource method @GET @Path("/order") public String getOrder(@QueryParam("id") Sting id) { ... } @Path("/order") @PUT public void putOrder(Order order) { ... }
  • 9.
    β€’ Unmarshalling –process of converting message content into Java object which is passed as parameter into resource method β€’ Entity providers are used for marshalling/unmarshalling Entity parameters
  • 10.
    β€’ Entity providers– specials Java classes β€’ Annotated with @Provider β€’ Implement javax.ws.rs.ext.MessageBodyReader [ isReadable(), readFrom() ] β€’ Entity provider is selected based on β€’ Content type specified with @Consumes annotation β€’ Content-Type HTTP header in request β€’ Java Class of entity parameter β€’ There are interesting built-in entity providers Entity providers
  • 11.
    β€’ Jersey performsWEB-INF/lib scanning for entity providers β€’ RESTEasy by default performs WEB-INF/lib scanning for entity providers, parameter resteasy.scan.providers does not work [ https://issues.jboss.org/browse/RESTEASY-1504 ] Automated scanning for entity providers
  • 12.
    β€’ Attacker selectsentity provider which is not intended for unmarshalling, by manipulating with Content-Type header of HTTP request Entity provider selection confusion attack
  • 13.
    β€’ Occur whenresource or resource method does not specify preferred content type via @Consumes annotation β€’ Or specifies it too permissive β€’ */* β€’ application/* β€’ And in some cases when content type is β€’ multipart/* β€’ multipart/form-data β€’ etc Entity provider selection confusion attack
  • 14.
    β€’ Impact ofattack β€’ RCE β€’ DoS β€’ CSRF β€’ XXE β€’ etc Entity provider selection confusion attack
  • 15.
    β€’ RESTEasy bydefault has SerializableProvider entity provider β€’ Vulnerable resource method doConcat() Attack for RESTEasy [ CVE-2016-7050 ] @POST @Path("/concat") @Produces(MediaType.APPLICATION_JSON) public Map doConcat(Pair pair) { HashMap result = new HashMap(); result.put("Result", pair.getP1() + pair.getP2()); return result; } public class Pair implements Serializable { ... }
  • 16.
    β€’ isReadable() methodof SerializableProvider β€’ SerializableProvider is used when Content-Type is application/x-java- serialized-object and Java class of entity parameter is serializable Attack for RESTEasy [ CVE-2016-7050 ] public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { return (Serializable.class.isAssignableFrom(type)) && (APPLICATION_SERIALIZABLE_TYPE.getType().equals(mediaType.getType())) && (APPLICATION_SERIALIZABLE_TYPE.getSubtype().equals(mediaType.getSubtype())); }
  • 17.
    β€’ readFrom() methodof SerializableProvider Attack for RESTEasy [ CVE-2016-7050 ] public Serializable readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { BufferedInputStream bis = new BufferedInputStream(entityStream); ObjectInputStream ois = new ObjectInputStream(bis); try { return (Serializable)Serializable.class.cast(ois.readObject()); } catch (ClassNotFoundException e) { throw new WebApplicationException(e); } }
  • 18.
    Attack for RESTEasy[ CVE-2016-7050 ]
  • 19.
    Attack for RESTEasy[ CVE-2016-7050 ]
  • 20.
    β€’ Jersey hasdefault jersey-media-kryo entity provider β€’ Vulnerable resource method doShowSize() Attack for Jersey @POST @Path("/size") @Produces(MediaType.APPLICATION_JSON) public Map<String, String> doShowSize(ArrayList<Pair> pairs) { HashMap<String, String> result = new HashMap<String, String>(); result.put("Count", String.valueOf(pairs.size())); return result; }
  • 21.
    β€’ DoS payload- https://gist.github.com/coekie/a27cc406fc9f3dc7a70d Attack for Jersey
  • 22.
    β€’ DoS payload- https://gist.github.com/coekie/a27cc406fc9f3dc7a70d Attack for Jersey
  • 23.
    β€’ Narrow possiblecontent types for resource or resource method using @Consumes annotation β€’ Use multipart/*, multipart/form-data, etc. content types with caution β€’ Java deserialization bugs exist not only in RMI/JMX/JMS Takeaways