Skip to content

Enhance GraphQL request body checks to prevent 500 Error #726

Closed
@karlrwjohnson

Description

@karlrwjohnson

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.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions