From ac6f82f4ead6cef6f4e089c5c36fcfa74bd4b544 Mon Sep 17 00:00:00 2001 From: Evan Shaw Date: Tue, 28 Aug 2018 21:22:59 +1200 Subject: [PATCH] Only allow query operations on GET requests This mitigates the risk of CSRF attacks. Closes #317. --- handler/graphql.go | 5 +++++ handler/graphql_test.go | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/handler/graphql.go b/handler/graphql.go index ccb3b38748..87c3e66bb2 100644 --- a/handler/graphql.go +++ b/handler/graphql.go @@ -206,6 +206,11 @@ func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc return } + if op.Operation != ast.Query && r.Method == http.MethodGet { + sendErrorf(w, http.StatusUnprocessableEntity, "GET requests only allow query operations") + return + } + vars, err := validator.VariableValues(exec.Schema(), op, reqParams.Variables) if err != nil { sendError(w, http.StatusUnprocessableEntity, err) diff --git a/handler/graphql_test.go b/handler/graphql_test.go index 4ace5d4131..685c9b994a 100644 --- a/handler/graphql_test.go +++ b/handler/graphql_test.go @@ -75,6 +75,12 @@ func TestHandlerGET(t *testing.T) { assert.Equal(t, http.StatusUnprocessableEntity, resp.Code) assert.Equal(t, `{"data":null,"errors":[{"message":"Unexpected !","locations":[{"line":1,"column":1}]}]}`, resp.Body.String()) }) + + t.Run("no mutations", func(t *testing.T) { + resp := doRequest(h, "GET", "/graphql?query=mutation{me{name}}", "") + assert.Equal(t, http.StatusUnprocessableEntity, resp.Code) + assert.Equal(t, `{"data":null,"errors":[{"message":"GET requests only allow query operations"}]}`, resp.Body.String()) + }) } func TestHandlerOptions(t *testing.T) {