fix: issues caught by fuzzer

This commit is contained in:
Vikram 2020-05-31 14:11:28 -07:00
parent 6102f1d66e
commit e82e97a9d7
10 changed files with 197 additions and 91 deletions

View File

@ -74,7 +74,7 @@ func (sg *SuperGraph) initConfig() error {
} }
if c.RolesQuery == "" { if c.RolesQuery == "" {
sg.log.Printf("WRN roles_query not defined: attribute based access control disabled") sg.log.Printf("INF roles_query not defined: attribute based access control disabled")
} }
_, userExists := sg.roles["user"] _, userExists := sg.roles["user"]

View File

@ -11,7 +11,7 @@ import (
var ( var (
qcompileTest, _ = qcode.NewCompiler(qcode.Config{}) qcompileTest, _ = qcode.NewCompiler(qcode.Config{})
schema = GetTestSchema() schema, _ = GetTestSchema()
vars = map[string]string{ vars = map[string]string{
"admin_account_id": "5", "admin_account_id": "5",
@ -25,6 +25,37 @@ var (
// FuzzerEntrypoint for Fuzzbuzz // FuzzerEntrypoint for Fuzzbuzz
func Fuzz(data []byte) int { func Fuzz(data []byte) int {
err1 := query(data)
err2 := insert(data)
err3 := update(data)
err4 := delete(data)
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
return 0
}
return 1
}
func query(data []byte) error {
gql := data
qc, err1 := qcompileTest.Compile(gql, "user")
vars := map[string]json.RawMessage{
"data": json.RawMessage(data),
}
_, _, err2 := pcompileTest.CompileEx(qc, vars)
if err1 != nil {
return err1
} else {
return err2
}
}
func insert(data []byte) error {
gql := `mutation { gql := `mutation {
product(insert: $data) { product(insert: $data) {
id id
@ -47,9 +78,57 @@ func Fuzz(data []byte) int {
} }
_, _, err = pcompileTest.CompileEx(qc, vars) _, _, err = pcompileTest.CompileEx(qc, vars)
return err
}
func update(data []byte) error {
gql := `mutation {
product(insert: $data) {
id
name
user {
id
full_name
email
}
}
}`
qc, err := qcompileTest.Compile([]byte(gql), "user")
if err != nil { if err != nil {
return 0 panic("qcompile can't fail")
} }
return 1 vars := map[string]json.RawMessage{
"data": json.RawMessage(data),
}
_, _, err = pcompileTest.CompileEx(qc, vars)
return err
}
func delete(data []byte) error {
gql := `mutation {
product(insert: $data) {
id
name
user {
id
full_name
email
}
}
}`
qc, err := qcompileTest.Compile([]byte(gql), "user")
if err != nil {
panic("qcompile can't fail")
}
vars := map[string]json.RawMessage{
"data": json.RawMessage(data),
}
_, _, err = pcompileTest.CompileEx(qc, vars)
return err
} }

View File

@ -0,0 +1,20 @@
// +build gofuzz
package psql
import (
"testing"
)
var ret int
func TestFuzzCrashers(t *testing.T) {
var crashers = []string{
"{\"connect\":{}}",
"q(q{q{q{q{q{q{q{q{",
}
for _, f := range crashers {
ret = Fuzz([]byte(f))
}
}

View File

@ -542,6 +542,10 @@ func (c *compilerContext) renderConnectStmt(qc *qcode.QCode, w io.Writer,
rel := item.relPC rel := item.relPC
if rel == nil {
return errors.New("invalid connect value")
}
// Render only for parent-to-child relationship of one-to-one // Render only for parent-to-child relationship of one-to-one
// For this to work the child needs to found first so it's primary key // For this to work the child needs to found first so it's primary key
// can be set in the related column on the parent object. // can be set in the related column on the parent object.

View File

@ -80,6 +80,10 @@ func (co *Compiler) CompileEx(qc *qcode.QCode, vars Variables) (Metadata, []byte
} }
func (co *Compiler) Compile(w io.Writer, qc *qcode.QCode, vars Variables) (Metadata, error) { func (co *Compiler) Compile(w io.Writer, qc *qcode.QCode, vars Variables) (Metadata, error) {
if qc == nil {
return Metadata{}, fmt.Errorf("qcode is nil")
}
switch qc.Type { switch qc.Type {
case qcode.QTQuery: case qcode.QTQuery:
return co.compileQuery(w, qc, vars) return co.compileQuery(w, qc, vars)
@ -1353,8 +1357,6 @@ func squoted(w io.Writer, identifier string) {
io.WriteString(w, `'`) io.WriteString(w, `'`)
} }
const charset = "0123456789"
func int32String(w io.Writer, val int32) { func int32String(w io.Writer, val int32) {
io.WriteString(w, strconv.FormatInt(int64(val), 10)) io.WriteString(w, strconv.FormatInt(int64(val), 10))
} }

View File

@ -201,6 +201,7 @@ func (p *Parser) peek(types ...itemType) bool {
// if p.items[n]._type == itemEOF { // if p.items[n]._type == itemEOF {
// return false // return false
// } // }
if n >= len(p.items) { if n >= len(p.items) {
return false return false
} }
@ -299,7 +300,7 @@ func (p *Parser) parseFields(fields []Field) ([]Field, error) {
return nil, fmt.Errorf("too many fields (max %d)", maxFields) return nil, fmt.Errorf("too many fields (max %d)", maxFields)
} }
if p.peek(itemObjClose) { if p.peek(itemEOF, itemObjClose) {
p.ignore() p.ignore()
st.Pop() st.Pop()
@ -385,7 +386,7 @@ func (p *Parser) parseOpParams(args []Arg) ([]Arg, error) {
return nil, fmt.Errorf("too many args (max %d)", maxArgs) return nil, fmt.Errorf("too many args (max %d)", maxArgs)
} }
if p.peek(itemArgsClose) { if p.peek(itemEOF, itemArgsClose) {
p.ignore() p.ignore()
break break
} }
@ -403,7 +404,7 @@ func (p *Parser) parseArgs(args []Arg) ([]Arg, error) {
return nil, fmt.Errorf("too many args (max %d)", maxArgs) return nil, fmt.Errorf("too many args (max %d)", maxArgs)
} }
if p.peek(itemArgsClose) { if p.peek(itemEOF, itemArgsClose) {
p.ignore() p.ignore()
break break
} }
@ -470,7 +471,7 @@ func (p *Parser) parseObj() (*Node, error) {
parent.Reset() parent.Reset()
for { for {
if p.peek(itemObjClose) { if p.peek(itemEOF, itemObjClose) {
p.ignore() p.ignore()
break break
} }

1
go.mod
View File

@ -18,6 +18,7 @@ require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dlclark/regexp2 v1.2.0 // indirect github.com/dlclark/regexp2 v1.2.0 // indirect
github.com/dop251/goja v0.0.0-20200424152103-d0b8fda54cd0 github.com/dop251/goja v0.0.0-20200424152103-d0b8fda54cd0
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813 // indirect
github.com/fsnotify/fsnotify v1.4.9 github.com/fsnotify/fsnotify v1.4.9
github.com/garyburd/redigo v1.6.0 github.com/garyburd/redigo v1.6.0
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect

2
go.sum
View File

@ -87,6 +87,8 @@ github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dop251/goja v0.0.0-20200424152103-d0b8fda54cd0 h1:EfFAcaAwGai/wlDCWwIObHBm3T2C2CCPX/SaS0fpOJ4= github.com/dop251/goja v0.0.0-20200424152103-d0b8fda54cd0 h1:EfFAcaAwGai/wlDCWwIObHBm3T2C2CCPX/SaS0fpOJ4=
github.com/dop251/goja v0.0.0-20200424152103-d0b8fda54cd0/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= github.com/dop251/goja v0.0.0-20200424152103-d0b8fda54cd0/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813 h1:NgO45/5mBLRVfiXerEFzH6ikcZ7DNRPS639xFg3ENzU=
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=

File diff suppressed because one or more lines are too long

View File

@ -12,56 +12,53 @@ var ret int
func TestFuzzCrashers(t *testing.T) { func TestFuzzCrashers(t *testing.T) {
var crashers = []string{ var crashers = []string{
/* "00\"0000\"0{",
"00\"0000\"0{", "6\",\n\t\t\t\"something\": " +
"6\",\n\t\t\t\"something\": " + "null\n\t\t},\n\t\t{\n\t\t\t\"id" +
"null\n\t\t},\n\t\t{\n\t\t\t\"id" + "\": 12,\n\t\t\t\"full_name" +
"\": 12,\n\t\t\t\"full_name" + "\": \"Brenton Bauch Ph" +
"\": \"Brenton Bauch Ph" + "D\",\n\t\t\t\"email\": \"ren" +
"D\",\n\t\t\t\"email\": \"ren" + "ee@miller.co\",\n\t\t\t\"_" +
"ee@miller.co\",\n\t\t\t\"_" + "_twitter_id\": 1\n\t\t}," +
"_twitter_id\": 1\n\t\t}," + "\n\t\t{\n\t\t\t\"id\": 13,\n\t\t" +
"\n\t\t{\n\t\t\t\"id\": 13,\n\t\t" + "\t\"full_name\": \"Daine" +
"\t\"full_name\": \"Daine" + " Gleichner\",\n\t\t\t\"ema" +
" Gleichner\",\n\t\t\t\"ema" + "il\": \"andrea@gmail.c" +
"il\": \"andrea@gmail.c" + "om\",\n\t\t\t\"__twitter_i" +
"om\",\n\t\t\t\"__twitter_i" + "d\": \"\",\n\t\t\t\"id__twit" +
"d\": \"\",\n\t\t\t\"id__twit" + "ter_id\": \"NOOO\",\n\t\t\t" +
"ter_id\": \"NOOO\",\n\t\t\t" + "\"work_email\": \"andre" +
"\"work_email\": \"andre" + "a@nienow.co\"\n\t\t}\n\t]}" +
"a@nienow.co\"\n\t\t}\n\t]}" + "\n\t}",
"\n\t}", "0000\"0000\"0{",
"0000\"0000\"0{", "0000\"\"{",
"0000\"\"{", "0000\"000\"{",
"0000\"000\"{", "0\"\"{",
"0\"\"{", "\"0\"{",
"\"0\"{", "000\"0\"{",
"000\"0\"{", "0\"0000\"0{",
"0\"0000\"0{", "000\"\"{",
"000\"\"{", "0\"00\"{",
"0\"00\"{", "000\"0000\"0{",
"000\"0000\"0{", "000\"00\"{",
"000\"00\"{", "\"\"{",
"\"\"{", "0\"0000\"{",
"0\"0000\"{", "\"000\"00{",
"\"000\"00{", "0000\"00\"{",
"0000\"00\"{", "00\"0\"{",
"00\"0\"{", "0\"0\"{",
"0\"0\"{", "000\"0000\"{",
"000\"0000\"{", "00\"0000\"{",
"00\"0000\"{", "0000\"0000\"{",
"0000\"0000\"{", "\"000\"{",
"\"000\"{", "00\"00\"{",
"00\"00\"{", "00\"0000\"00{",
"00\"0000\"00{", "0\"0000\"00{",
"0\"0000\"00{", "00\"\"{",
"00\"\"{", "0000\"0\"{",
"0000\"0\"{", "000\"000\"{",
"000\"000\"{", "\"00000000\"{",
"\"00000000\"{", `0000"00"00000000"000000000"00"000000000000000"00000"00000": "00"0"__twitter_id": [{ "name": "hello" }, { "name": "world"}]`,
`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"}]`, `0000"000000000000000000000000000000000000"00000000"000000000"00"000000000000000"00000"00000": "00000000000000"00000"__twitter_id": [{ "name": "hello" }, { "name": "world"}]`,
`00"__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" + "\"\xb0\xef\xbd\xe3\xbd\xef\x99\xe3\xbd\xef\xbd\xef\xbd\xef\xbd\xe5\x99\xe3\xbd" +