From 0a02bde219d7e72b631bcc2055af57367d390389 Mon Sep 17 00:00:00 2001 From: Vikram Rangnekar Date: Mon, 20 Apr 2020 02:06:58 -0400 Subject: [PATCH] fix: block introspection queries in production mode --- core/api.go | 26 ++++++++++++++++---------- internal/serv/http.go | 9 +++++++-- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/core/api.go b/core/api.go index 2ddee37..c660c08 100644 --- a/core/api.go +++ b/core/api.go @@ -160,15 +160,24 @@ type Result struct { // In developer mode all names queries are saved into a file `allow.list` and in production mode only // queries from this file can be run. func (sg *SuperGraph) GraphQL(c context.Context, query string, vars json.RawMessage) (*Result, error) { - // try to use the sg.Engine to execute introspection queries... - res := sg.Engine.ExecuteOne(&graphql.EngineRequest{ Query: query}) - if res.Error()==nil { - r := &Result{} - r.Data = res.Data - return r, nil + var res Result + + res.op = qcode.GetQType(query) + res.name = allow.QueryName(query) + + // use the chirino/graphql library for introspection queries + // disabled when allow list is enforced + if !sg.conf.UseAllowList && + res.op == qcode.QTQuery && + res.name == "IntrospectionQuery" { + + r := sg.Engine.ExecuteOne(&graphql.EngineRequest{Query: query}) + res.Data = r.Data + + return &res, r.Error() } - ct := scontext{Context: c, sg: sg, query: query, vars: vars} + ct := scontext{Context: c, sg: sg, query: query, vars: vars, res: res} if len(vars) <= 2 { ct.vars = nil @@ -180,9 +189,6 @@ func (sg *SuperGraph) GraphQL(c context.Context, query string, vars json.RawMess ct.role = "anon" } - ct.res.op = qcode.GetQType(query) - ct.res.name = allow.QueryName(query) - data, err := ct.execQuery() if err != nil { return &ct.res, err diff --git a/internal/serv/http.go b/internal/serv/http.go index 54afef9..f73430d 100644 --- a/internal/serv/http.go +++ b/internal/serv/http.go @@ -74,9 +74,14 @@ func apiV1(w http.ResponseWriter, r *http.Request) { return } + doLog := true res, err := sg.GraphQL(ct, req.Query, req.Vars) - if logLevel >= LogLevelDebug { + if !conf.Production && res.QueryName() == "IntrospectionQuery" { + doLog = false + } + + if doLog && logLevel >= LogLevelDebug { log.Printf("DBG query %s: %s", res.QueryName(), res.SQL()) } @@ -87,7 +92,7 @@ func apiV1(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(res) - if logLevel >= LogLevelInfo { + if doLog && logLevel >= LogLevelInfo { zlog.Info("success", zap.String("op", res.Operation()), zap.String("name", res.QueryName()),