Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/cmd/integration-test/library.go
2070 views
1
package main
2
3
import (
4
"context"
5
"fmt"
6
"log"
7
"net/http"
8
"net/http/httptest"
9
"os"
10
"path"
11
"strings"
12
"time"
13
14
"github.com/julienschmidt/httprouter"
15
"github.com/logrusorgru/aurora"
16
"github.com/pkg/errors"
17
"github.com/projectdiscovery/goflags"
18
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
19
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/disk"
20
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/loader"
21
"github.com/projectdiscovery/nuclei/v3/pkg/core"
22
"github.com/projectdiscovery/nuclei/v3/pkg/input/provider"
23
parsers "github.com/projectdiscovery/nuclei/v3/pkg/loader/workflow"
24
"github.com/projectdiscovery/nuclei/v3/pkg/output"
25
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
26
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/hosterrorscache"
27
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/interactsh"
28
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolinit"
29
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
30
"github.com/projectdiscovery/nuclei/v3/pkg/reporting"
31
"github.com/projectdiscovery/nuclei/v3/pkg/templates"
32
"github.com/projectdiscovery/nuclei/v3/pkg/testutils"
33
"github.com/projectdiscovery/nuclei/v3/pkg/types"
34
"github.com/projectdiscovery/ratelimit"
35
)
36
37
var libraryTestcases = []TestCaseInfo{
38
{Path: "library/test.yaml", TestCase: &goIntegrationTest{}},
39
{Path: "library/test.json", TestCase: &goIntegrationTest{}},
40
}
41
42
type goIntegrationTest struct{}
43
44
// Execute executes a test case and returns an error if occurred
45
//
46
// Execute the docs at ../DESIGN.md if the code stops working for integration.
47
func (h *goIntegrationTest) Execute(templatePath string) error {
48
router := httprouter.New()
49
50
router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
51
_, _ = fmt.Fprintf(w, "This is test matcher text")
52
if strings.EqualFold(r.Header.Get("test"), "nuclei") {
53
_, _ = fmt.Fprintf(w, "This is test headers matcher text")
54
}
55
})
56
ts := httptest.NewServer(router)
57
defer ts.Close()
58
59
results, err := executeNucleiAsLibrary(templatePath, ts.URL)
60
if err != nil {
61
return err
62
}
63
return expectResultsCount(results, 1)
64
}
65
66
// executeNucleiAsLibrary contains an example
67
func executeNucleiAsLibrary(templatePath, templateURL string) ([]string, error) {
68
cache := hosterrorscache.New(30, hosterrorscache.DefaultMaxHostsCount, nil)
69
defer cache.Close()
70
71
defaultOpts := types.DefaultOptions()
72
defaultOpts.ExecutionId = "test"
73
74
mockProgress := &testutils.MockProgressClient{}
75
reportingClient, err := reporting.New(&reporting.Options{ExecutionId: defaultOpts.ExecutionId}, "", false)
76
if err != nil {
77
return nil, err
78
}
79
defer reportingClient.Close()
80
81
_ = protocolstate.Init(defaultOpts)
82
_ = protocolinit.Init(defaultOpts)
83
84
defer protocolstate.Close(defaultOpts.ExecutionId)
85
86
defaultOpts.Templates = goflags.StringSlice{templatePath}
87
defaultOpts.ExcludeTags = config.ReadIgnoreFile().Tags
88
89
outputWriter := testutils.NewMockOutputWriter(defaultOpts.OmitTemplate)
90
var results []string
91
outputWriter.WriteCallback = func(event *output.ResultEvent) {
92
results = append(results, fmt.Sprintf("%v\n", event))
93
}
94
95
interactOpts := interactsh.DefaultOptions(outputWriter, reportingClient, mockProgress)
96
interactClient, err := interactsh.New(interactOpts)
97
if err != nil {
98
return nil, errors.Wrap(err, "could not create interact client")
99
}
100
defer interactClient.Close()
101
102
home, _ := os.UserHomeDir()
103
catalog := disk.NewCatalog(path.Join(home, "nuclei-templates"))
104
ratelimiter := ratelimit.New(context.Background(), 150, time.Second)
105
defer ratelimiter.Stop()
106
107
executerOpts := &protocols.ExecutorOptions{
108
Output: outputWriter,
109
Options: defaultOpts,
110
Progress: mockProgress,
111
Catalog: catalog,
112
IssuesClient: reportingClient,
113
RateLimiter: ratelimiter,
114
Interactsh: interactClient,
115
HostErrorsCache: cache,
116
Colorizer: aurora.NewAurora(true),
117
ResumeCfg: types.NewResumeCfg(),
118
Parser: templates.NewParser(),
119
}
120
engine := core.New(defaultOpts)
121
engine.SetExecuterOptions(executerOpts)
122
123
workflowLoader, err := parsers.NewLoader(executerOpts)
124
if err != nil {
125
log.Fatalf("Could not create workflow loader: %s\n", err)
126
}
127
executerOpts.WorkflowLoader = workflowLoader
128
129
store, err := loader.New(loader.NewConfig(defaultOpts, catalog, executerOpts))
130
if err != nil {
131
return nil, errors.Wrap(err, "could not create loader")
132
}
133
store.Load()
134
135
_ = engine.Execute(context.Background(), store.Templates(), provider.NewSimpleInputProviderWithUrls(defaultOpts.ExecutionId, templateURL))
136
engine.WorkPool().Wait() // Wait for the scan to finish
137
138
return results, nil
139
}
140
141