-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraphql_validation_security.go
More file actions
112 lines (96 loc) · 2.75 KB
/
Copy pathgraphql_validation_security.go
File metadata and controls
112 lines (96 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package graph
import (
"strings"
)
// MaxDepthRule validates maximum query depth
type MaxDepthRule struct {
BaseRule
maxDepth int
}
// NewMaxDepthRule creates a new max depth validation rule
func NewMaxDepthRule(maxDepth int) ValidationRule {
return &MaxDepthRule{
BaseRule: NewBaseRule("MaxDepthRule"),
maxDepth: maxDepth,
}
}
func (r *MaxDepthRule) Validate(ctx *ValidationContext) error {
depth := calculateQueryDepth(ctx.Document, 0)
if depth > r.maxDepth {
return r.NewErrorf("query depth %d exceeds maximum %d", depth, r.maxDepth)
}
return nil
}
// MaxComplexityRule validates query complexity
type MaxComplexityRule struct {
BaseRule
maxComplexity int
}
// NewMaxComplexityRule creates a new max complexity validation rule
func NewMaxComplexityRule(maxComplexity int) ValidationRule {
return &MaxComplexityRule{
BaseRule: NewBaseRule("MaxComplexityRule"),
maxComplexity: maxComplexity,
}
}
func (r *MaxComplexityRule) Validate(ctx *ValidationContext) error {
complexity := calculateQueryComplexity(ctx.Document, 1)
if complexity > r.maxComplexity {
return r.NewErrorf("query complexity %d exceeds maximum %d", complexity, r.maxComplexity)
}
return nil
}
// MaxAliasesRule validates number of aliases
type MaxAliasesRule struct {
BaseRule
maxAliases int
}
// NewMaxAliasesRule creates a new max aliases validation rule
func NewMaxAliasesRule(maxAliases int) ValidationRule {
return &MaxAliasesRule{
BaseRule: NewBaseRule("MaxAliasesRule"),
maxAliases: maxAliases,
}
}
func (r *MaxAliasesRule) Validate(ctx *ValidationContext) error {
count := countAliases(ctx.Document)
if count > r.maxAliases {
return r.NewErrorf("query contains %d aliases, maximum %d allowed", count, r.maxAliases)
}
return nil
}
// NoIntrospectionRule blocks introspection queries
type NoIntrospectionRule struct {
BaseRule
}
// NewNoIntrospectionRule creates a new no introspection validation rule
func NewNoIntrospectionRule() ValidationRule {
return &NoIntrospectionRule{
BaseRule: NewBaseRule("NoIntrospectionRule"),
}
}
func (r *NoIntrospectionRule) Validate(ctx *ValidationContext) error {
if hasIntrospection(ctx.Document) {
return r.NewError("GraphQL introspection is disabled")
}
return nil
}
// MaxTokensRule limits query size by token count
type MaxTokensRule struct {
BaseRule
maxTokens int
}
// NewMaxTokensRule creates a new max tokens validation rule
func NewMaxTokensRule(maxTokens int) ValidationRule {
return &MaxTokensRule{
BaseRule: NewBaseRule("MaxTokensRule"),
maxTokens: maxTokens,
}
}
func (r *MaxTokensRule) Validate(ctx *ValidationContext) error {
tokens := len(strings.Fields(ctx.Query))
if tokens > r.maxTokens {
return r.NewErrorf("query contains %d tokens, maximum %d allowed", tokens, r.maxTokens)
}
return nil
}