From 7f6d677b9fef7ad8628a9799133367072c51c6e1 Mon Sep 17 00:00:00 2001 From: Yuval Moravchick Date: Wed, 3 Jan 2024 15:46:35 +0200 Subject: [PATCH 1/7] Add directive limit to prevent overloading --- parser/query.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/parser/query.go b/parser/query.go index a7840b27..62e072a8 100644 --- a/parser/query.go +++ b/parser/query.go @@ -1,6 +1,8 @@ package parser import ( + "fmt" + "github.com/vektah/gqlparser/v2/lexer" //nolint:revive @@ -315,12 +317,21 @@ func (p *parser) parseObjectField(isConst bool) *ChildValue { func (p *parser) parseDirectives(isConst bool) []*Directive { var directives []*Directive + directiveCount := 0 + maxDirectiveLimit := 10 // Define a reasonable limit for p.peek().Kind == lexer.At { if p.err != nil { break } directives = append(directives, p.parseDirective(isConst)) + directiveCount++ + + // Set an internal parser error if the directive limit is exceeded + if directiveCount > maxDirectiveLimit { + p.err = fmt.Errorf("exceeded directive limit of %d", maxDirectiveLimit) + break // Stop processing further directives + } } return directives } From 4211fc83f0e17d6db56fde8b918ad54763479452 Mon Sep 17 00:00:00 2001 From: Yuval Moravchick Date: Thu, 11 Jan 2024 11:39:49 +0200 Subject: [PATCH 2/7] Added token limit to parser for query and schema parsing, removed my previous directive limit --- parser/parser.go | 10 ++++++++++ parser/query.go | 14 ++------------ parser/schema.go | 3 ++- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/parser/parser.go b/parser/parser.go index ef03c414..d8f81aeb 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -1,6 +1,7 @@ package parser import ( + "fmt" "strconv" "github.com/vektah/gqlparser/v2/ast" @@ -20,6 +21,9 @@ type parser struct { comment *ast.CommentGroup commentConsuming bool + + tokenCount int + maxTokenLimit int } func (p *parser) consumeComment() (*ast.Comment, bool) { @@ -95,6 +99,12 @@ func (p *parser) next() lexer.Token { if p.err != nil { return p.prev } + // Increment the token count before reading the next token + p.tokenCount++ + if p.tokenCount > p.maxTokenLimit { + p.err = fmt.Errorf("exceeded token limit of %d", p.maxTokenLimit) + return p.prev + } if p.peeked { p.peeked = false p.comment = nil diff --git a/parser/query.go b/parser/query.go index 62e072a8..fed6737a 100644 --- a/parser/query.go +++ b/parser/query.go @@ -1,17 +1,15 @@ package parser import ( - "fmt" - "github.com/vektah/gqlparser/v2/lexer" - //nolint:revive . "github.com/vektah/gqlparser/v2/ast" ) func ParseQuery(source *Source) (*QueryDocument, error) { p := parser{ - lexer: lexer.New(source), + lexer: lexer.New(source), + maxTokenLimit: 15000, // 15000 is the default value } return p.parseQueryDocument(), p.err } @@ -317,21 +315,13 @@ func (p *parser) parseObjectField(isConst bool) *ChildValue { func (p *parser) parseDirectives(isConst bool) []*Directive { var directives []*Directive - directiveCount := 0 - maxDirectiveLimit := 10 // Define a reasonable limit for p.peek().Kind == lexer.At { if p.err != nil { break } directives = append(directives, p.parseDirective(isConst)) - directiveCount++ - // Set an internal parser error if the directive limit is exceeded - if directiveCount > maxDirectiveLimit { - p.err = fmt.Errorf("exceeded directive limit of %d", maxDirectiveLimit) - break // Stop processing further directives - } } return directives } diff --git a/parser/schema.go b/parser/schema.go index 9b13d0ca..f0121734 100644 --- a/parser/schema.go +++ b/parser/schema.go @@ -20,7 +20,8 @@ func ParseSchemas(inputs ...*Source) (*SchemaDocument, error) { func ParseSchema(source *Source) (*SchemaDocument, error) { p := parser{ - lexer: lexer.New(source), + lexer: lexer.New(source), + maxTokenLimit: 15000, // default value } sd, err := p.parseSchemaDocument(), p.err if err != nil { From a4c3b66e9d3208d4fe42258c79f75c80ba322495 Mon Sep 17 00:00:00 2001 From: Yuval Moravchick Date: Thu, 11 Jan 2024 11:47:37 +0200 Subject: [PATCH 3/7] Added token limit to parser for query and schema parsing, removed my previous directive limit --- parser/parser_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/parser/parser_test.go b/parser/parser_test.go index 16eb0308..2235901e 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -166,5 +166,8 @@ func TestParserUtils(t *testing.T) { } func newParser(input string) parser { - return parser{lexer: lexer.New(&ast.Source{Input: input, Name: "input.graphql"})} + return parser{ + lexer: lexer.New(&ast.Source{Input: input, Name: "input.graphql"}), + maxTokenLimit: 15000, // 15000 is the default value + } } From 316604e48668c6676137e53bd2a37a4a732e4279 Mon Sep 17 00:00:00 2001 From: Steve Coffman Date: Thu, 11 Jan 2024 14:23:02 -0500 Subject: [PATCH 4/7] Update parser/parser.go --- parser/parser.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/parser/parser.go b/parser/parser.go index d8f81aeb..e9bdcdca 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -26,6 +26,10 @@ type parser struct { maxTokenLimit int } +func (p *parser) SetMaxTokenLimit(maxToken int) { + p.maxTokenLimit = maxToken +} + func (p *parser) consumeComment() (*ast.Comment, bool) { if p.err != nil { return nil, false From 5b793d2768bcdabfea3ac1ed5ed523e993a60cfa Mon Sep 17 00:00:00 2001 From: Steve Coffman Date: Thu, 11 Jan 2024 14:23:07 -0500 Subject: [PATCH 5/7] Update parser/parser.go --- parser/parser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser/parser.go b/parser/parser.go index e9bdcdca..bfcf7ea4 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -105,7 +105,7 @@ func (p *parser) next() lexer.Token { } // Increment the token count before reading the next token p.tokenCount++ - if p.tokenCount > p.maxTokenLimit { + if p.maxTokenLimit != 0 && p.tokenCount > p.maxTokenLimit { p.err = fmt.Errorf("exceeded token limit of %d", p.maxTokenLimit) return p.prev } From f1ffdaf8337211d5c313702a69e413157332f79b Mon Sep 17 00:00:00 2001 From: Steve Coffman Date: Thu, 11 Jan 2024 14:23:14 -0500 Subject: [PATCH 6/7] Update parser/query.go --- parser/query.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser/query.go b/parser/query.go index fed6737a..e55b21fe 100644 --- a/parser/query.go +++ b/parser/query.go @@ -9,7 +9,7 @@ import ( func ParseQuery(source *Source) (*QueryDocument, error) { p := parser{ lexer: lexer.New(source), - maxTokenLimit: 15000, // 15000 is the default value + maxTokenLimit: 0, // 0 is the default value } return p.parseQueryDocument(), p.err } From d6689addacc778a4cac572bcb2d41f1c4e6b4395 Mon Sep 17 00:00:00 2001 From: Steve Coffman Date: Tue, 11 Jun 2024 16:33:53 -0400 Subject: [PATCH 7/7] Fix lint Signed-off-by: Steve Coffman --- parser/query.go | 1 - 1 file changed, 1 deletion(-) diff --git a/parser/query.go b/parser/query.go index e55b21fe..eb2a8e81 100644 --- a/parser/query.go +++ b/parser/query.go @@ -321,7 +321,6 @@ func (p *parser) parseDirectives(isConst bool) []*Directive { break } directives = append(directives, p.parseDirective(isConst)) - } return directives }