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