I am using Jersey in my Web-application. The data sent to the server is in JSON format, which in turn is unmarshalled at the server-end and the object obtained is used in further processing. The security audit raised some vulnerabilities for this approach.
My Rest Code:
@POST
@Path("/registerManga")
@Produces(MediaType.APPLICATION_JSON)
public Response registerManga(MangaBean mBean){
System.out.println(mBean);
return Response.status(200).build();
}
MangaBean:
public class MangaBean {
public String title;
public String author;
@Override
public String toString() {
return "MangaBean [title=" + title + ", author=" + author + "]";
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
The data is sent in this format:
["title":"Bleach","author":"kubo tite"]
The above data is successfully unmarshalled into an object and I get this as the output:
MangaBean [title=Bleach, author=kubo tite]
But if the data is changed to:
["title":"<script>alert("123");</script>","author":"kubo tite"]
A 500 internal server error occurs and is displayed to the user:
javax.servlet.ServletException: org.codehaus.jackson.JsonParseException: Unexpected character ('1' (code 49)): was expecting comma to separate OBJECT entries
at [Source: org.apache.catalina.connector.CoyoteInputStream@19bd1ca; line: 1, column: 28]
com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:420)
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
The unexpected occurrence of ""
is causing errors in the parser. As the unmarshalling is done behind the scenes and I have no control over it, I am unable to handle the exception being raised.
My question is how can I handle this exception and return a proper response to the user instead of a stacktrace. Please advice.
Register an exception mapper to handle the JSON parsing exceptions:
@Provider
class JSONParseExceptionMapper implements ExceptionMapper< JsonParseException > {
@Override
public Response toResponse(final JsonParseException jpe) {
// Create and return an appropriate response here
return Response.status(Status.BAD_REQUEST)
.entity("Invalid data supplied for request").build();
}
}
If this exception mapper isn't being called (as John Ding's comment indicated), make sure you have it registered with your ResourceConfig.
Also, take note that when using the JacksonFeature (with Jersey 2.x) it includes an exception mapper for this, but if you register your own it will take precedence.
Here is an example of registering it by package. So put JSONParseExceptionMapper in "your.package.here" and it will get picked up.
@ApplicationPath("whatever")
public class MyAppResourceConfig extends ResourceConfig
{
public MyAppResourceConfig()
{
packages("your.package.here");
register(JacksonFeature.class);
}
}
For the original question, you'll need to handle JsonMappingExceptionMapper as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With