Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/fuzz/fuzz_test.go
2070 views
1
package fuzz
2
3
import (
4
"testing"
5
6
"github.com/projectdiscovery/goflags"
7
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
8
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/variables"
9
"github.com/projectdiscovery/nuclei/v3/pkg/types"
10
"github.com/projectdiscovery/nuclei/v3/pkg/utils"
11
"github.com/stretchr/testify/require"
12
)
13
14
func TestRuleMatchKeyOrValue(t *testing.T) {
15
rule := &Rule{
16
Part: "query",
17
}
18
err := rule.Compile(nil, nil)
19
require.NoError(t, err, "could not compile rule")
20
21
result := rule.matchKeyOrValue("url", "")
22
require.True(t, result, "could not get correct result")
23
24
t.Run("key", func(t *testing.T) {
25
rule := &Rule{Keys: []string{"url"}, Part: "query"}
26
err := rule.Compile(nil, nil)
27
require.NoError(t, err, "could not compile rule")
28
29
result := rule.matchKeyOrValue("url", "")
30
require.True(t, result, "could not get correct result")
31
result = rule.matchKeyOrValue("test", "")
32
require.False(t, result, "could not get correct result")
33
})
34
t.Run("value", func(t *testing.T) {
35
rule := &Rule{ValuesRegex: []string{`https?:\/\/?([-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b)*(\/[\/\d\w\.-]*)*(?:[\?])*(.+)*`}, Part: "query"}
36
err := rule.Compile(nil, nil)
37
require.NoError(t, err, "could not compile rule")
38
39
result := rule.matchKeyOrValue("", "http://localhost:80")
40
require.True(t, result, "could not get correct result")
41
result = rule.matchKeyOrValue("test", "random")
42
require.False(t, result, "could not get correct result")
43
})
44
}
45
46
func TestEvaluateVariables(t *testing.T) {
47
t.Run("keys", func(t *testing.T) {
48
rule := &Rule{
49
Keys: []string{"{{foo_var}}"},
50
Part: "query",
51
}
52
53
// mock
54
templateVars := variables.Variable{
55
InsertionOrderedStringMap: *utils.NewEmptyInsertionOrderedStringMap(1),
56
}
57
templateVars.Set("foo_var", "foo_var_value")
58
59
constants := map[string]interface{}{
60
"const_key": "const_value",
61
}
62
63
options := &types.Options{}
64
65
// runtime vars (to simulate CLI)
66
runtimeVars := goflags.RuntimeMap{}
67
_ = runtimeVars.Set("runtime_key=runtime_value")
68
options.Vars = runtimeVars
69
70
executorOpts := &protocols.ExecutorOptions{
71
Variables: templateVars,
72
Constants: constants,
73
Options: options,
74
}
75
76
err := rule.Compile(nil, executorOpts)
77
require.NoError(t, err, "could not compile rule")
78
79
result := rule.matchKeyOrValue("foo_var_value", "test_value")
80
require.True(t, result, "should match evaluated variable key")
81
82
result = rule.matchKeyOrValue("{{foo_var}}", "test_value")
83
require.False(t, result, "should not match unevaluated variable key")
84
})
85
86
t.Run("keys-regex", func(t *testing.T) {
87
rule := &Rule{
88
KeysRegex: []string{"^{{foo_var}}"},
89
Part: "query",
90
}
91
92
templateVars := variables.Variable{
93
InsertionOrderedStringMap: *utils.NewEmptyInsertionOrderedStringMap(1),
94
}
95
templateVars.Set("foo_var", "foo_var_value")
96
97
executorOpts := &protocols.ExecutorOptions{
98
Variables: templateVars,
99
Constants: map[string]interface{}{},
100
Options: &types.Options{},
101
}
102
103
err := rule.Compile(nil, executorOpts)
104
require.NoError(t, err, "could not compile rule")
105
106
result := rule.matchKeyOrValue("foo_var_value", "test_value")
107
require.True(t, result, "should match evaluated variable in regex")
108
109
result = rule.matchKeyOrValue("other_key", "test_value")
110
require.False(t, result, "should not match non-matching key")
111
})
112
113
t.Run("values-regex", func(t *testing.T) {
114
rule := &Rule{
115
ValuesRegex: []string{"{{foo_var}}"},
116
Part: "query",
117
}
118
119
templateVars := variables.Variable{
120
InsertionOrderedStringMap: *utils.NewEmptyInsertionOrderedStringMap(1),
121
}
122
templateVars.Set("foo_var", "test_pattern")
123
124
executorOpts := &protocols.ExecutorOptions{
125
Variables: templateVars,
126
Constants: map[string]interface{}{},
127
Options: &types.Options{},
128
}
129
130
err := rule.Compile(nil, executorOpts)
131
require.NoError(t, err, "could not compile rule")
132
133
result := rule.matchKeyOrValue("test_key", "test_pattern")
134
require.True(t, result, "should match evaluated variable in values regex")
135
136
result = rule.matchKeyOrValue("test_key", "other_value")
137
require.False(t, result, "should not match non-matching value")
138
})
139
140
// complex vars w/ consts and runtime vars
141
t.Run("complex-variables", func(t *testing.T) {
142
rule := &Rule{
143
Keys: []string{"{{template_var}}", "{{const_key}}", "{{runtime_key}}"},
144
Part: "query",
145
}
146
147
templateVars := variables.Variable{
148
InsertionOrderedStringMap: *utils.NewEmptyInsertionOrderedStringMap(1),
149
}
150
templateVars.Set("template_var", "template_value")
151
152
constants := map[string]interface{}{
153
"const_key": "const_value",
154
}
155
156
options := &types.Options{}
157
runtimeVars := goflags.RuntimeMap{}
158
_ = runtimeVars.Set("runtime_key=runtime_value")
159
options.Vars = runtimeVars
160
161
executorOpts := &protocols.ExecutorOptions{
162
Variables: templateVars,
163
Constants: constants,
164
Options: options,
165
}
166
167
err := rule.Compile(nil, executorOpts)
168
require.NoError(t, err, "could not compile rule")
169
170
result := rule.matchKeyOrValue("template_value", "test")
171
require.True(t, result, "should match template variable")
172
173
result = rule.matchKeyOrValue("const_value", "test")
174
require.True(t, result, "should match constant")
175
176
result = rule.matchKeyOrValue("runtime_value", "test")
177
require.True(t, result, "should match runtime variable")
178
179
result = rule.matchKeyOrValue("{{template_var}}", "test")
180
require.False(t, result, "should not match unevaluated template variable")
181
})
182
183
t.Run("invalid-variables", func(t *testing.T) {
184
rule := &Rule{
185
Keys: []string{"{{nonexistent_var}}"},
186
Part: "query",
187
}
188
189
executorOpts := &protocols.ExecutorOptions{
190
Variables: variables.Variable{
191
InsertionOrderedStringMap: *utils.NewEmptyInsertionOrderedStringMap(0),
192
},
193
Constants: map[string]interface{}{},
194
Options: &types.Options{},
195
}
196
197
err := rule.Compile(nil, executorOpts)
198
if err != nil {
199
require.Contains(t, err.Error(), "unresolved", "error should mention unresolved variables")
200
} else {
201
result := rule.matchKeyOrValue("some_key", "some_value")
202
require.False(t, result, "should not match when variables are unresolved")
203
}
204
})
205
206
t.Run("evaluateVars-function", func(t *testing.T) {
207
rule := &Rule{}
208
209
templateVars := variables.Variable{
210
InsertionOrderedStringMap: *utils.NewEmptyInsertionOrderedStringMap(1),
211
}
212
templateVars.Set("test_var", "test_value")
213
214
constants := map[string]interface{}{
215
"const_var": "const_value",
216
}
217
218
options := &types.Options{}
219
runtimeVars := goflags.RuntimeMap{}
220
_ = runtimeVars.Set("runtime_var=runtime_value")
221
options.Vars = runtimeVars
222
223
executorOpts := &protocols.ExecutorOptions{
224
Variables: templateVars,
225
Constants: constants,
226
Options: options,
227
}
228
229
rule.options = executorOpts
230
231
// Test simple var substitution
232
result, err := rule.evaluateVars("{{test_var}}")
233
require.NoError(t, err, "should evaluate template variable")
234
require.Equal(t, "test_value", result, "should return evaluated value")
235
236
// Test constant substitution
237
result, err = rule.evaluateVars("{{const_var}}")
238
require.NoError(t, err, "should evaluate constant")
239
require.Equal(t, "const_value", result, "should return constant value")
240
241
// Test runtime var substitution
242
result, err = rule.evaluateVars("{{runtime_var}}")
243
require.NoError(t, err, "should evaluate runtime variable")
244
require.Equal(t, "runtime_value", result, "should return runtime value")
245
246
// Test mixed content
247
result, err = rule.evaluateVars("prefix-{{test_var}}-suffix")
248
require.NoError(t, err, "should evaluate mixed content")
249
require.Equal(t, "prefix-test_value-suffix", result, "should return mixed evaluated content")
250
251
// Test unresolved var - should either fail during evaluation or return original string
252
result2, err := rule.evaluateVars("{{nonexistent}}")
253
if err != nil {
254
require.Contains(t, err.Error(), "unresolved", "should fail for unresolved variable")
255
} else {
256
// If no error, it should return the original unresolved variable
257
require.Equal(t, "{{nonexistent}}", result2, "should return original string for unresolved variable")
258
}
259
})
260
}
261
262