From 6102f1d66e277955773346d9ac02c67723111c97 Mon Sep 17 00:00:00 2001 From: Vikram Date: Sat, 30 May 2020 23:34:28 -0700 Subject: [PATCH] fix: infinite loop on missing allow.list issue --- core/internal/allow/allow.go | 14 ++++- core/prepare.go | 7 +-- go.mod | 1 + go.sum | 5 ++ internal/serv/cmd.go | 4 +- jsn/clear.go | 8 ++- jsn/fuzz_test.go | 106 +++++++++++++++++++---------------- jsn/replace.go | 9 +++ 8 files changed, 98 insertions(+), 56 deletions(-) diff --git a/core/internal/allow/allow.go b/core/internal/allow/allow.go index e0cfe93..2121b54 100644 --- a/core/internal/allow/allow.go +++ b/core/internal/allow/allow.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io/ioutil" + "log" "os" "sort" "strings" @@ -35,6 +36,7 @@ type List struct { type Config struct { CreateIfNotExists bool Persist bool + Log *log.Logger } func New(filename string, conf Config) (*List, error) { @@ -80,6 +82,12 @@ func New(filename string, conf Config) (*List, error) { } else { al.filepath = filename } + + if file, err := os.OpenFile(al.filepath, os.O_RDONLY|os.O_CREATE, 0644); err != nil { + return nil, err + } else { + file.Close() + } } var err error @@ -89,8 +97,10 @@ func New(filename string, conf Config) (*List, error) { go func() { for v := range al.saveChan { - if err = al.save(v); err != nil { - break + err := al.save(v) + + if err != nil && conf.Log != nil { + conf.Log.Println("WRN allow list save:", err) } } }() diff --git a/core/prepare.go b/core/prepare.go index d554dca..ba746af 100644 --- a/core/prepare.go +++ b/core/prepare.go @@ -187,15 +187,14 @@ func (sg *SuperGraph) initAllowList() error { var ac allow.Config var err error - if len(sg.conf.AllowListFile) == 0 { - sg.conf.UseAllowList = false - sg.log.Printf("WRN allow list disabled no file specified") + if sg.conf.AllowListFile == "" { + sg.conf.AllowListFile = "allow.list" } // When list is not eabled it is still created and // and new queries are saved to it. if !sg.conf.UseAllowList { - ac = allow.Config{CreateIfNotExists: true, Persist: true} + ac = allow.Config{CreateIfNotExists: true, Persist: true, Log: sg.log} } sg.allowList, err = allow.New(sg.conf.AllowListFile, ac) diff --git a/go.mod b/go.mod index 405b913..97a40c5 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/openzipkin/zipkin-go v0.2.2 github.com/pelletier/go-toml v1.7.0 // indirect github.com/pkg/errors v0.9.1 + github.com/prometheus/common v0.4.0 github.com/rs/cors v1.7.0 github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cast v1.3.1 // indirect diff --git a/go.sum b/go.sum index 8b04d78..e451841 100644 --- a/go.sum +++ b/go.sum @@ -35,7 +35,9 @@ github.com/adjust/gorails v0.0.0-20171013043634-2786ed0c03d3 h1:+qz9Ga6l6lKw6fgv github.com/adjust/gorails v0.0.0-20171013043634-2786ed0c03d3/go.mod h1:FlkD11RtgMTYjVuBnb7cxoHmQGqvPpCsr2atC88nl/M= github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aws/aws-sdk-go v1.15.27 h1:i75BxN4Es/8rTVQbEKAP1WCiIhhz635xTNeDdZJRAXQ= @@ -220,6 +222,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -319,6 +322,7 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -543,6 +547,7 @@ google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/serv/cmd.go b/internal/serv/cmd.go index e53c51f..7524a43 100644 --- a/internal/serv/cmd.go +++ b/internal/serv/cmd.go @@ -156,7 +156,7 @@ func cmdVersion(cmd *cobra.Command, args []string) { func BuildDetails() string { if len(version) == 0 { - return fmt.Sprintf(` + return ` Super Graph (unknown version) For documentation, visit https://supergraph.dev @@ -166,7 +166,7 @@ To build with version information please use the Makefile Licensed under the Apache Public License 2.0 Copyright 2020, Vikram Rangnekar -`) +` } return fmt.Sprintf(` diff --git a/jsn/clear.go b/jsn/clear.go index cac5550..7f33193 100644 --- a/jsn/clear.go +++ b/jsn/clear.go @@ -3,6 +3,7 @@ package jsn import ( "bytes" "encoding/json" + "errors" "io" ) @@ -68,7 +69,12 @@ func Clear(w *bytes.Buffer, v []byte) error { } io := int(dec.InputOffset()) - w.Write(v[io-len(v1)-2 : io]) + s := io - len(v1) - 2 + if io <= s || s <= 0 { + return errors.New("invalid json") + } + + w.Write(v[s:io]) w.WriteString(`:`) isValue = true diff --git a/jsn/fuzz_test.go b/jsn/fuzz_test.go index d99a24b..4b1d0fa 100644 --- a/jsn/fuzz_test.go +++ b/jsn/fuzz_test.go @@ -8,57 +8,69 @@ import ( "github.com/dosco/super-graph/jsn" ) +var ret int + func TestFuzzCrashers(t *testing.T) { var crashers = []string{ - "00\"0000\"0{", - "6\",\n\t\t\t\"something\": " + - "null\n\t\t},\n\t\t{\n\t\t\t\"id" + - "\": 12,\n\t\t\t\"full_name" + - "\": \"Brenton Bauch Ph" + - "D\",\n\t\t\t\"email\": \"ren" + - "ee@miller.co\",\n\t\t\t\"_" + - "_twitter_id\": 1\n\t\t}," + - "\n\t\t{\n\t\t\t\"id\": 13,\n\t\t" + - "\t\"full_name\": \"Daine" + - " Gleichner\",\n\t\t\t\"ema" + - "il\": \"andrea@gmail.c" + - "om\",\n\t\t\t\"__twitter_i" + - "d\": \"\",\n\t\t\t\"id__twit" + - "ter_id\": \"NOOO\",\n\t\t\t" + - "\"work_email\": \"andre" + - "a@nienow.co\"\n\t\t}\n\t]}" + - "\n\t}", - "0000\"0000\"0{", - "0000\"\"{", - "0000\"000\"{", - "0\"\"{", - "\"0\"{", - "000\"0\"{", - "0\"0000\"0{", - "000\"\"{", - "0\"00\"{", - "000\"0000\"0{", - "000\"00\"{", - "\"\"{", - "0\"0000\"{", - "\"000\"00{", - "0000\"00\"{", - "00\"0\"{", - "0\"0\"{", - "000\"0000\"{", - "00\"0000\"{", - "0000\"0000\"{", - "\"000\"{", - "00\"00\"{", - "00\"0000\"00{", - "0\"0000\"00{", - "00\"\"{", - "0000\"0\"{", - "000\"000\"{", - "\"00000000\"{", + /* + "00\"0000\"0{", + "6\",\n\t\t\t\"something\": " + + "null\n\t\t},\n\t\t{\n\t\t\t\"id" + + "\": 12,\n\t\t\t\"full_name" + + "\": \"Brenton Bauch Ph" + + "D\",\n\t\t\t\"email\": \"ren" + + "ee@miller.co\",\n\t\t\t\"_" + + "_twitter_id\": 1\n\t\t}," + + "\n\t\t{\n\t\t\t\"id\": 13,\n\t\t" + + "\t\"full_name\": \"Daine" + + " Gleichner\",\n\t\t\t\"ema" + + "il\": \"andrea@gmail.c" + + "om\",\n\t\t\t\"__twitter_i" + + "d\": \"\",\n\t\t\t\"id__twit" + + "ter_id\": \"NOOO\",\n\t\t\t" + + "\"work_email\": \"andre" + + "a@nienow.co\"\n\t\t}\n\t]}" + + "\n\t}", + "0000\"0000\"0{", + "0000\"\"{", + "0000\"000\"{", + "0\"\"{", + "\"0\"{", + "000\"0\"{", + "0\"0000\"0{", + "000\"\"{", + "0\"00\"{", + "000\"0000\"0{", + "000\"00\"{", + "\"\"{", + "0\"0000\"{", + "\"000\"00{", + "0000\"00\"{", + "00\"0\"{", + "0\"0\"{", + "000\"0000\"{", + "00\"0000\"{", + "0000\"0000\"{", + "\"000\"{", + "00\"00\"{", + "00\"0000\"00{", + "0\"0000\"00{", + "00\"\"{", + "0000\"0\"{", + "000\"000\"{", + "\"00000000\"{", + `0000"00"00000000"000000000"00"000000000000000"00000"00000": "00"0"__twitter_id": [{ "name": "hello" }, { "name": "world"}]`, + */ + + `0000"000000000000000000000000000000000000"00000000"000000000"00"000000000000000"00000"00000": "00000000000000"00000"__twitter_id": [{ "name": "hello" }, { "name": "world"}]`, + `00"__twitter_id":[{ "name": "hello" }, { "name": "world"}]`, + "\"\xb0\xef\xbd\xe3\xbd\xef\x99\xe3\xbd\xef\xbd\xef\xbd\xef\xbd\xe5\x99\xe3\xbd" + + "\xef\x99\xe3\"", + "\"\xef\xe3\xef\xe3\xe3\xe3\xef\xe3\xe3\xef\xe3\xef\xe3\xe3\xe3\xef\xe3\xef\xe3" + + "\xe3\xef\xef\xef\xe5\xe3\xef\xe3\xc6\xef\xef\xef\xe5\xe3\xef\xe3\xc6\xef\xef\"", } for _, f := range crashers { - _ = jsn.Fuzz([]byte(f)) + ret = jsn.Fuzz([]byte(f)) } } diff --git a/jsn/replace.go b/jsn/replace.go index ae95274..3a7ceaf 100644 --- a/jsn/replace.go +++ b/jsn/replace.go @@ -133,9 +133,18 @@ func Replace(w *bytes.Buffer, b []byte, from, to []Field) error { if e != 0 { e++ + if e <= s { + return errors.New("invalid json") + } + if _, err := h.Write(b[s:e]); err != nil { return err } + + if (we + 1) <= ws { + return errors.New("invalid json") + } + n, ok := tmap[h.Sum64()] h.Reset()