Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: safe http error response #2438

Merged
merged 6 commits into from Dec 3, 2022
Merged

Conversation

koniuszy
Copy link
Contributor

@koniuszy koniuszy commented Nov 28, 2022

I cannot intercept the error of an invalid request using the hooks. I always get:

{
  "errors": [
    {
      "message": "json body could not be decoded: json: cannot unmarshal array into Go value of type graphql.RawParams"
    }
  ],
  "data": null
}

This change removes from the response the details of a decoding error, and instead returns a StatusBadRequest with a more generic decoding error. The more specific error is instead logged.

Before:

{"errors":[{"message":"json body could not be decoded: invalid character 'o' in literal null (expecting 'u')"}],"data":null}

After:

{"errors":[{"message":"json body could not be decoded"}],"data":null}

I have:

  • Added tests covering the bug / feature (see testing)
  • Updated any relevant documentation (see docs)

Solved:
#2430

@koniuszy koniuszy changed the title safe http error when parsing body fix: safe http error response which does not mention programming language Nov 28, 2022
@koniuszy koniuszy changed the title fix: safe http error response which does not mention programming language fix: safe http error response Nov 28, 2022
@coveralls
Copy link

coveralls commented Nov 28, 2022

Coverage Status

Coverage decreased (-0.04%) to 75.395% when pulling 142fc3b on koniuszy:patch-1 into f28ffcc on 99designs:master.

@StevenACoffman
Copy link
Collaborator

Hi. Rather than remove the displaying information from those who want it, can we instead look for a way to avoid having the hook be unable to parse it?

Do you have a small repository where you can reproduce the original problem?

@koniuszy
Copy link
Contributor Author

koniuszy commented Nov 28, 2022

hey @StevenACoffman, thanks for the reply,

Initially I tried to control the error with the hooks but to no avail.
This could be controlled by a config flag or some sort of an error hook. At the moment it's a security leak and in my opinion it should be disabled by default asap.

If it does not persuade you, please point the direction so I could at least try implementing what's requested.

@crossworth
Copy link
Contributor

Hello @koniuszy, maybe another way to solve this would to implement a custom graphql.Transport and use it instead of the default transport.POST.

srv.AddTransport(transport.MyCustomPOST{})

koniuszy and others added 3 commits December 1, 2022 15:49
Signed-off-by: Steve Coffman <steve@khanacademy.org>
Signed-off-by: Steve Coffman <steve@khanacademy.org>
@StevenACoffman
Copy link
Collaborator

StevenACoffman commented Dec 3, 2022

Thanks! So there were actually multiple problems that this uncovered.

The main one was that decoding errors were not dispatched, so the hooks had no ability to intercept errors to present the error as you wished. There was also a potential nil pointer dereference which would cause panic and bypass the error presenter hook (although the recover panic would catch that one).

I modified your example repository to add a hook. With that change and using this updated PR to gqlgen it will not present the details you wanted to be obscured:

const defaultPort = "8080"

func main() {
	port := os.Getenv("PORT")
	if port == "" {
		port = defaultPort
	}

	srv := handler.NewDefaultServer(MakeExecutableSchema(&graph.Resolver{}))
	srv.SetErrorPresenter(func(ctx context.Context, e error) *gqlerror.Error {
		fmt.Printf("Got error here: %+v", e)
		err := graphql.DefaultErrorPresenter(ctx, e)
		err.Message = "Eeek!"

		return err
	})

	http.Handle("/", playground.Handler("GraphQL playground", "/query"))
	http.Handle("/query", srv)

	log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))
}

func MakeExecutableSchema(resolvers *graph.Resolver) graphql.ExecutableSchema {
	return generated.NewExecutableSchema(generated.Config{Resolvers: resolvers})
}
➜  ~ curl --compressed -i 'http://localhost:8080/query' -X POST -H 'Content-Type: application/json' --data-raw '[]'
HTTP/1.1 400 Bad Request
Content-Type: application/json
Date: Sat, 03 Dec 2022 18:43:52 GMT
Content-Length: 44

{"errors":[{"message":"Eeek!"}],"data":null}

@StevenACoffman StevenACoffman merged commit 463d213 into 99designs:master Dec 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants