Description
An automated scanning tool at my organization found that when the request body is not well-formed, Spring GraphQL (tested v. 1.0.4) generates 500 Internal Server Error
where 400 Bad Request
is expected.
Consider the following example request:
POST /graphql
Content-Type: application/json
{
"query": "query { foo }",
"variables": "&/usr/bin/env&"
}
Obviously variables
should be an object, not a string. One would expect this request to product a 400 Bad Request
messsage, but instead the server returns 500 Internal Server Error
:
{
"timestamp": "2023-06-19T15:47:12.050+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "class java.lang.String cannot be cast to class java.util.Map (java.lang.String and java.util.Map are in module java.base of loader 'bootstrap')",
"path": "/graphql"
}
Stack trace:
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [/] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.Map (java.lang.String and java.util.Map are in module java.base of loader 'bootstrap')] with root cause
java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.Map (java.lang.String and java.util.Map are in module java.base of loader 'bootstrap')
at org.springframework.graphql.server.WebGraphQlRequest.<init>(WebGraphQlRequest.java:61)
at org.springframework.graphql.server.webmvc.GraphQlHttpHandler.handleRequest(GraphQlHttpHandler.java:85)
at org.springframework.web.servlet.function.support.HandlerFunctionAdapter.handle(HandlerFunctionAdapter.java:106)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:665)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
...
The error occurs when WebGraphQLRequest
extracts the variables
key of the request via <T> T getKey(String key, Map<String, Object> body)
.
Only the presence of the key is checked, not its type. getKey()
could expect a ParameterizedTypeReference<T>
of the expected type, or the caller could use a library like Jackson to reinterpret the request body into a class with known-type keys.
As it stands, I'm looking at writing a custom filter to detect and validate GraphQL requests, but it seems like something that would be better done inside the library.