Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/cmd/integration-test/loader.go
2070 views
1
package main
2
3
import (
4
"fmt"
5
"net/http"
6
"net/http/httptest"
7
"os"
8
"strings"
9
10
"github.com/julienschmidt/httprouter"
11
12
"github.com/projectdiscovery/nuclei/v3/pkg/testutils"
13
"github.com/projectdiscovery/utils/errkit"
14
permissionutil "github.com/projectdiscovery/utils/permission"
15
)
16
17
var loaderTestcases = []TestCaseInfo{
18
{Path: "loader/template-list.yaml", TestCase: &remoteTemplateList{}},
19
{Path: "loader/workflow-list.yaml", TestCase: &remoteWorkflowList{}},
20
{Path: "loader/excluded-template.yaml", TestCase: &excludedTemplate{}},
21
{Path: "loader/nonexistent-template-list.yaml", TestCase: &nonExistentTemplateList{}},
22
{Path: "loader/nonexistent-workflow-list.yaml", TestCase: &nonExistentWorkflowList{}},
23
{Path: "loader/template-list-not-allowed.yaml", TestCase: &remoteTemplateListNotAllowed{}},
24
{Path: "loader/load-template-with-id", TestCase: &loadTemplateWithID{}},
25
}
26
27
type remoteTemplateList struct{}
28
29
// Execute executes a test case and returns an error if occurred
30
func (h *remoteTemplateList) Execute(templateList string) error {
31
router := httprouter.New()
32
33
router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
34
_, _ = fmt.Fprintf(w, "This is test matcher text")
35
if strings.EqualFold(r.Header.Get("test"), "nuclei") {
36
_, _ = fmt.Fprintf(w, "This is test headers matcher text")
37
}
38
})
39
40
router.GET("/template_list", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
41
file, err := os.ReadFile(templateList)
42
if err != nil {
43
w.WriteHeader(500)
44
}
45
_, err = w.Write(file)
46
if err != nil {
47
w.WriteHeader(500)
48
}
49
})
50
ts := httptest.NewServer(router)
51
defer ts.Close()
52
53
configFileData := `remote-template-domain: [ "` + ts.Listener.Addr().String() + `" ]`
54
err := os.WriteFile("test-config.yaml", []byte(configFileData), permissionutil.ConfigFilePermission)
55
if err != nil {
56
return err
57
}
58
defer func() {
59
_ = os.Remove("test-config.yaml")
60
}()
61
62
results, err := testutils.RunNucleiBareArgsAndGetResults(debug, nil, "-target", ts.URL, "-template-url", ts.URL+"/template_list", "-config", "test-config.yaml")
63
if err != nil {
64
return err
65
}
66
67
return expectResultsCount(results, 2)
68
}
69
70
type excludedTemplate struct{}
71
72
// Execute executes a test case and returns an error if occurred
73
func (h *excludedTemplate) Execute(templateList string) error {
74
router := httprouter.New()
75
76
router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
77
_, _ = fmt.Fprintf(w, "This is test matcher text")
78
if strings.EqualFold(r.Header.Get("test"), "nuclei") {
79
_, _ = fmt.Fprintf(w, "This is test headers matcher text")
80
}
81
})
82
ts := httptest.NewServer(router)
83
defer ts.Close()
84
85
results, err := testutils.RunNucleiBareArgsAndGetResults(debug, nil, "-target", ts.URL, "-t", templateList, "-include-templates", templateList)
86
if err != nil {
87
return err
88
}
89
90
return expectResultsCount(results, 1)
91
}
92
93
type remoteTemplateListNotAllowed struct{}
94
95
// Execute executes a test case and returns an error if occurred
96
func (h *remoteTemplateListNotAllowed) Execute(templateList string) error {
97
router := httprouter.New()
98
99
router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
100
_, _ = fmt.Fprintf(w, "This is test matcher text")
101
if strings.EqualFold(r.Header.Get("test"), "nuclei") {
102
_, _ = fmt.Fprintf(w, "This is test headers matcher text")
103
}
104
})
105
106
router.GET("/template_list", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
107
file, err := os.ReadFile(templateList)
108
if err != nil {
109
w.WriteHeader(500)
110
}
111
_, err = w.Write(file)
112
if err != nil {
113
w.WriteHeader(500)
114
}
115
})
116
ts := httptest.NewServer(router)
117
defer ts.Close()
118
119
_, err := testutils.RunNucleiBareArgsAndGetResults(debug, nil, "-target", ts.URL, "-template-url", ts.URL+"/template_list")
120
if err == nil {
121
return fmt.Errorf("expected error for not allowed remote template list url")
122
}
123
124
return nil
125
126
}
127
128
type remoteWorkflowList struct{}
129
130
// Execute executes a test case and returns an error if occurred
131
func (h *remoteWorkflowList) Execute(workflowList string) error {
132
router := httprouter.New()
133
134
router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
135
_, _ = fmt.Fprintf(w, "This is test matcher text")
136
if strings.EqualFold(r.Header.Get("test"), "nuclei") {
137
_, _ = fmt.Fprintf(w, "This is test headers matcher text")
138
}
139
})
140
141
router.GET("/workflow_list", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
142
file, err := os.ReadFile(workflowList)
143
if err != nil {
144
w.WriteHeader(500)
145
}
146
_, err = w.Write(file)
147
if err != nil {
148
w.WriteHeader(500)
149
}
150
})
151
ts := httptest.NewServer(router)
152
defer ts.Close()
153
154
configFileData := `remote-template-domain: [ "` + ts.Listener.Addr().String() + `" ]`
155
err := os.WriteFile("test-config.yaml", []byte(configFileData), permissionutil.ConfigFilePermission)
156
if err != nil {
157
return err
158
}
159
defer func() {
160
_ = os.Remove("test-config.yaml")
161
}()
162
163
results, err := testutils.RunNucleiBareArgsAndGetResults(debug, nil, "-target", ts.URL, "-workflow-url", ts.URL+"/workflow_list", "-config", "test-config.yaml")
164
if err != nil {
165
return err
166
}
167
168
return expectResultsCount(results, 3)
169
}
170
171
type nonExistentTemplateList struct{}
172
173
// Execute executes a test case and returns an error if occurred
174
func (h *nonExistentTemplateList) Execute(nonExistingTemplateList string) error {
175
router := httprouter.New()
176
ts := httptest.NewServer(router)
177
defer ts.Close()
178
179
configFileData := `remote-template-domain: [ "` + ts.Listener.Addr().String() + `" ]`
180
err := os.WriteFile("test-config.yaml", []byte(configFileData), permissionutil.ConfigFilePermission)
181
if err != nil {
182
return err
183
}
184
defer func() {
185
_ = os.Remove("test-config.yaml")
186
}()
187
188
_, err = testutils.RunNucleiBareArgsAndGetResults(debug, nil, "-target", ts.URL, "-template-url", ts.URL+"/404", "-config", "test-config.yaml")
189
if err == nil {
190
return fmt.Errorf("expected error for nonexisting workflow url")
191
}
192
193
return nil
194
}
195
196
type nonExistentWorkflowList struct{}
197
198
// Execute executes a test case and returns an error if occurred
199
func (h *nonExistentWorkflowList) Execute(nonExistingWorkflowList string) error {
200
router := httprouter.New()
201
ts := httptest.NewServer(router)
202
defer ts.Close()
203
204
configFileData := `remote-template-domain: [ "` + ts.Listener.Addr().String() + `" ]`
205
err := os.WriteFile("test-config.yaml", []byte(configFileData), permissionutil.ConfigFilePermission)
206
if err != nil {
207
return err
208
}
209
defer func() {
210
_ = os.Remove("test-config.yaml")
211
}()
212
213
_, err = testutils.RunNucleiBareArgsAndGetResults(debug, nil, "-target", ts.URL, "-workflow-url", ts.URL+"/404", "-config", "test-config.yaml")
214
if err == nil {
215
return fmt.Errorf("expected error for nonexisting workflow url")
216
}
217
218
return nil
219
}
220
221
type loadTemplateWithID struct{}
222
223
func (h *loadTemplateWithID) Execute(nooop string) error {
224
results, err := testutils.RunNucleiBareArgsAndGetResults(debug, nil, "-target", "scanme.sh", "-id", "self-signed-ssl")
225
if err != nil {
226
return errkit.Wrap(err, "failed to load template with id")
227
}
228
return expectResultsCount(results, 1)
229
}
230
231