Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/operators/matchers/match_test.go
2070 views
1
package matchers
2
3
import (
4
"testing"
5
6
"github.com/Knetic/govaluate"
7
"github.com/projectdiscovery/nuclei/v3/pkg/operators/common/dsl"
8
"github.com/stretchr/testify/require"
9
)
10
11
func TestWordANDCondition(t *testing.T) {
12
m := &Matcher{condition: ANDCondition, Words: []string{"a", "b"}}
13
14
isMatched, matched := m.MatchWords("a b", nil)
15
require.True(t, isMatched, "Could not match words with valid AND condition")
16
require.Equal(t, m.Words, matched)
17
18
isMatched, matched = m.MatchWords("b", nil)
19
require.False(t, isMatched, "Could match words with invalid AND condition")
20
require.Equal(t, []string{}, matched)
21
}
22
23
func TestRegexANDCondition(t *testing.T) {
24
m := &Matcher{Type: MatcherTypeHolder{MatcherType: RegexMatcher}, Condition: "and", Regex: []string{"[a-z]{3}", "\\d{2}"}}
25
err := m.CompileMatchers()
26
require.Nil(t, err)
27
28
isMatched, matched := m.MatchRegex("abc abcd 123")
29
require.True(t, isMatched, "Could not match regex with valid AND condition")
30
require.Equal(t, []string{"abc", "abc", "12"}, matched)
31
32
isMatched, matched = m.MatchRegex("bc 1")
33
require.False(t, isMatched, "Could match regex with invalid AND condition")
34
require.Equal(t, []string{}, matched)
35
}
36
37
func TestORCondition(t *testing.T) {
38
m := &Matcher{condition: ORCondition, Words: []string{"a", "b"}}
39
40
isMatched, matched := m.MatchWords("a b", nil)
41
require.True(t, isMatched, "Could not match valid word OR condition")
42
require.Equal(t, []string{"a"}, matched)
43
44
isMatched, matched = m.MatchWords("b", nil)
45
require.True(t, isMatched, "Could not match valid word OR condition")
46
require.Equal(t, []string{"b"}, matched)
47
48
isMatched, matched = m.MatchWords("c", nil)
49
require.False(t, isMatched, "Could match invalid word OR condition")
50
require.Equal(t, []string{}, matched)
51
}
52
53
func TestRegexOrCondition(t *testing.T) {
54
m := &Matcher{Type: MatcherTypeHolder{MatcherType: RegexMatcher}, Condition: "or", Regex: []string{"[a-z]{3}", "\\d{2}"}}
55
err := m.CompileMatchers()
56
require.Nil(t, err)
57
58
isMatched, matched := m.MatchRegex("ab 123")
59
require.True(t, isMatched, "Could not match valid regex OR condition")
60
require.Equal(t, []string{"12"}, matched)
61
62
isMatched, matched = m.MatchRegex("bc 1")
63
require.False(t, isMatched, "Could match invalid regex OR condition")
64
require.Equal(t, []string{}, matched)
65
}
66
67
func TestHexEncoding(t *testing.T) {
68
m := &Matcher{Encoding: "hex", Type: MatcherTypeHolder{MatcherType: WordsMatcher}, Part: "body", Words: []string{"50494e47"}}
69
err := m.CompileMatchers()
70
require.Nil(t, err, "could not compile matcher")
71
72
isMatched, matched := m.MatchWords("PING", nil)
73
require.True(t, isMatched, "Could not match valid Hex condition")
74
require.Equal(t, m.Words, matched)
75
}
76
77
func TestMatcher_MatchDSL(t *testing.T) {
78
compiled, err := govaluate.NewEvaluableExpressionWithFunctions("contains(body, \"{{VARIABLE}}\")", dsl.HelperFunctions)
79
require.Nil(t, err, "couldn't compile expression")
80
81
m := &Matcher{Type: MatcherTypeHolder{MatcherType: DSLMatcher}, dslCompiled: []*govaluate.EvaluableExpression{compiled}}
82
err = m.CompileMatchers()
83
require.Nil(t, err, "could not compile matcher")
84
85
values := []string{"PING", "pong"}
86
87
for value := range values {
88
isMatched := m.MatchDSL(map[string]interface{}{"body": value, "VARIABLE": value})
89
require.True(t, isMatched)
90
}
91
}
92
93
func TestMatcher_MatchXPath_HTML(t *testing.T) {
94
body := `<!doctype html>
95
<html>
96
<head>
97
<title>Example Domain</title>
98
99
<meta charset="utf-8" />
100
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
101
<meta name="viewport" content="width=device-width, initial-scale=1" />
102
</head>
103
104
<body>
105
<div>
106
<h1>Example Domain</h1>
107
<p>This domain is for use in illustrative examples in documents. You may use this
108
domain in literature without prior coordination or asking for permission.</p>
109
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
110
</div>
111
</body>
112
</html>
113
`
114
body2 := `<!doctype html>
115
<html>
116
<head>
117
<title>Example Domain</title>
118
</head>
119
<body>
120
<h1> It's test time! </h1>
121
</body>
122
</html>
123
`
124
125
// single match
126
m := &Matcher{Type: MatcherTypeHolder{MatcherType: XPathMatcher}, XPath: []string{"/html/body/div/p[2]/a"}}
127
err := m.CompileMatchers()
128
require.Nil(t, err)
129
130
isMatched := m.MatchXPath(body)
131
require.True(t, isMatched, "Could not match valid XPath")
132
133
isMatched = m.MatchXPath("<h1>aaaaaaaaa")
134
require.False(t, isMatched, "Could match invalid XPath")
135
136
// OR match
137
m = &Matcher{Type: MatcherTypeHolder{MatcherType: XPathMatcher}, Condition: "or", XPath: []string{"/html/head/title[contains(text(), 'PATRICAAA')]", "/html/body/div/p[2]/a"}}
138
err = m.CompileMatchers()
139
require.Nil(t, err)
140
141
isMatched = m.MatchXPath(body)
142
require.True(t, isMatched, "Could not match valid multi-XPath with OR condition")
143
144
isMatched = m.MatchXPath(body2)
145
require.False(t, isMatched, "Could match invalid multi-XPath with OR condition")
146
147
// AND match
148
m = &Matcher{Type: MatcherTypeHolder{MatcherType: XPathMatcher}, Condition: "and", XPath: []string{"/html/head/title[contains(text(), 'Example Domain')]", "/html/body/div/p[2]/a"}}
149
err = m.CompileMatchers()
150
require.Nil(t, err)
151
152
isMatched = m.MatchXPath(body)
153
require.True(t, isMatched, "Could not match valid multi-XPath with AND condition")
154
155
isMatched = m.MatchXPath(body2)
156
require.False(t, isMatched, "Could match invalid multi-XPath with AND condition")
157
158
// invalid xpath
159
m = &Matcher{Type: MatcherTypeHolder{MatcherType: XPathMatcher}, XPath: []string{"//a[@a==1]"}}
160
_ = m.CompileMatchers()
161
isMatched = m.MatchXPath(body)
162
require.False(t, isMatched, "Invalid xpath did not return false")
163
}
164
165
func TestMatcher_MatchXPath_XML(t *testing.T) {
166
body := `<?xml version="1.0" encoding="utf-8"?><foo>bar</foo><wibble id="1" /><parent><child>baz</child></parent>`
167
body2 := `<?xml version="1.0" encoding="utf-8"?><test>bar</test><wibble2 id="1" /><roditelj><dijete>alo</dijete></roditelj>`
168
169
// single match
170
m := &Matcher{Type: MatcherTypeHolder{MatcherType: XPathMatcher}, XPath: []string{"//foo[contains(text(), 'bar')]"}}
171
err := m.CompileMatchers()
172
require.Nil(t, err)
173
174
isMatched := m.MatchXPath(body)
175
require.True(t, isMatched, "Could not match valid XPath")
176
177
isMatched = m.MatchXPath("<h1>aaaaaaaaa</h1>")
178
require.False(t, isMatched, "Could match invalid XPath")
179
180
// OR match
181
m = &Matcher{Type: MatcherTypeHolder{MatcherType: XPathMatcher}, Condition: "or", XPath: []string{"/foo[contains(text(), 'PATRICAAA')]", "/parent/child"}}
182
err = m.CompileMatchers()
183
require.Nil(t, err)
184
185
isMatched = m.MatchXPath(body)
186
require.True(t, isMatched, "Could not match valid multi-XPath with OR condition")
187
188
isMatched = m.MatchXPath(body2)
189
require.False(t, isMatched, "Could match invalid multi-XPath with OR condition")
190
191
// AND match
192
m = &Matcher{Type: MatcherTypeHolder{MatcherType: XPathMatcher}, Condition: "and", XPath: []string{"/foo[contains(text(), 'bar')]", "/parent/child"}}
193
err = m.CompileMatchers()
194
require.Nil(t, err)
195
196
isMatched = m.MatchXPath(body)
197
require.True(t, isMatched, "Could not match valid multi-XPath with AND condition")
198
199
isMatched = m.MatchXPath(body2)
200
require.False(t, isMatched, "Could match invalid multi-XPath with AND condition")
201
202
// invalid xpath
203
m = &Matcher{Type: MatcherTypeHolder{MatcherType: XPathMatcher}, XPath: []string{"//a[@a==1]"}}
204
_ = m.CompileMatchers()
205
isMatched = m.MatchXPath(body)
206
require.False(t, isMatched, "Invalid xpath did not return false")
207
208
// invalid xml
209
isMatched = m.MatchXPath("<h1> not right <q id=2/>notvalid")
210
require.False(t, isMatched, "Invalid xpath did not return false")
211
}
212
213