github.com/projectdiscovery/nuclei/v2@v2.9.15/pkg/protocols/http/request_test.go (about) 1 package http 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/http/httptest" 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/projectdiscovery/nuclei/v2/pkg/model" 12 "github.com/projectdiscovery/nuclei/v2/pkg/model/types/severity" 13 "github.com/projectdiscovery/nuclei/v2/pkg/operators" 14 "github.com/projectdiscovery/nuclei/v2/pkg/operators/extractors" 15 "github.com/projectdiscovery/nuclei/v2/pkg/operators/matchers" 16 "github.com/projectdiscovery/nuclei/v2/pkg/output" 17 "github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs" 18 "github.com/projectdiscovery/nuclei/v2/pkg/testutils" 19 ) 20 21 func TestHTTPExtractMultipleReuse(t *testing.T) { 22 options := testutils.DefaultOptions 23 24 testutils.Init(options) 25 templateID := "testing-http" 26 request := &Request{ 27 ID: templateID, 28 Raw: []string{ 29 `GET /robots.txt HTTP/1.1 30 Host: {{Hostname}} 31 User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0 32 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 33 Accept-Language: en-US,en;q=0.5 34 `, 35 36 `GET {{endpoint}} HTTP/1.1 37 Host: {{Hostname}} 38 User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0 39 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 40 Accept-Language: en-US,en;q=0.5 41 `, 42 }, 43 Operators: operators.Operators{ 44 Matchers: []*matchers.Matcher{{ 45 Part: "body", 46 Type: matchers.MatcherTypeHolder{MatcherType: matchers.WordsMatcher}, 47 Words: []string{"match /a", "match /b", "match /c"}, 48 }}, 49 Extractors: []*extractors.Extractor{{ 50 Part: "body", 51 Name: "endpoint", 52 Type: extractors.ExtractorTypeHolder{ExtractorType: extractors.RegexExtractor}, 53 Regex: []string{"(?m)/([a-zA-Z0-9-_/\\\\]+)"}, 54 Internal: true, 55 }}, 56 }, 57 IterateAll: true, 58 } 59 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 60 switch r.URL.Path { 61 case "/robots.txt": 62 _, _ = w.Write([]byte(`User-agent: Googlebot 63 Disallow: /a 64 Disallow: /b 65 Disallow: /c`)) 66 default: 67 _, _ = w.Write([]byte(fmt.Sprintf(`match %v`, r.URL.Path))) 68 } 69 })) 70 defer ts.Close() 71 72 executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{ 73 ID: templateID, 74 Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"}, 75 }) 76 77 err := request.Compile(executerOpts) 78 require.Nil(t, err, "could not compile network request") 79 80 var finalEvent *output.InternalWrappedEvent 81 var matchCount int 82 t.Run("test", func(t *testing.T) { 83 metadata := make(output.InternalEvent) 84 previous := make(output.InternalEvent) 85 ctxArgs := contextargs.NewWithInput(ts.URL) 86 err := request.ExecuteWithResults(ctxArgs, metadata, previous, func(event *output.InternalWrappedEvent) { 87 if event.OperatorsResult != nil && event.OperatorsResult.Matched { 88 matchCount++ 89 } 90 finalEvent = event 91 }) 92 require.Nil(t, err, "could not execute network request") 93 }) 94 require.NotNil(t, finalEvent, "could not get event output from request") 95 require.Equal(t, 3, matchCount, "could not get correct match count") 96 } 97 98 func TestDisableTE(t *testing.T) { 99 options := testutils.DefaultOptions 100 101 testutils.Init(options) 102 templateID := "http-disable-transfer-encoding" 103 104 // in raw request format 105 request := &Request{ 106 ID: templateID, 107 Raw: []string{ 108 `POST / HTTP/1.1 109 Host: {{Hostname}} 110 User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0 111 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 112 Accept-Language: en-US,en;q=0.5 113 114 login=1&username=admin&password=admin 115 `, 116 }, 117 Operators: operators.Operators{ 118 Matchers: []*matchers.Matcher{{ 119 Type: matchers.MatcherTypeHolder{MatcherType: matchers.StatusMatcher}, 120 Status: []int{200}, 121 }}, 122 }, 123 } 124 125 // in base request format 126 request2 := &Request{ 127 ID: templateID, 128 Method: HTTPMethodTypeHolder{MethodType: HTTPPost}, 129 Path: []string{"{{BaseURL}}"}, 130 Body: "login=1&username=admin&password=admin", 131 Operators: operators.Operators{ 132 Matchers: []*matchers.Matcher{{ 133 Type: matchers.MatcherTypeHolder{MatcherType: matchers.StatusMatcher}, 134 Status: []int{200}, 135 }}, 136 }, 137 } 138 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 139 if len(r.TransferEncoding) > 0 || r.ContentLength <= 0 { 140 t.Error("Transfer-Encoding header should not be set") 141 } 142 })) 143 defer ts.Close() 144 145 executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{ 146 ID: templateID, 147 Info: model.Info{SeverityHolder: severity.Holder{Severity: severity.Low}, Name: "test"}, 148 }) 149 150 err := request.Compile(executerOpts) 151 require.Nil(t, err, "could not compile http raw request") 152 153 err = request2.Compile(executerOpts) 154 require.Nil(t, err, "could not compile http base request") 155 156 var finalEvent *output.InternalWrappedEvent 157 var matchCount int 158 t.Run("test", func(t *testing.T) { 159 metadata := make(output.InternalEvent) 160 previous := make(output.InternalEvent) 161 ctxArgs := contextargs.NewWithInput(ts.URL) 162 err := request.ExecuteWithResults(ctxArgs, metadata, previous, func(event *output.InternalWrappedEvent) { 163 if event.OperatorsResult != nil && event.OperatorsResult.Matched { 164 matchCount++ 165 } 166 finalEvent = event 167 }) 168 require.Nil(t, err, "could not execute network request") 169 }) 170 171 t.Run("test2", func(t *testing.T) { 172 metadata := make(output.InternalEvent) 173 previous := make(output.InternalEvent) 174 ctxArgs := contextargs.NewWithInput(ts.URL) 175 err := request2.ExecuteWithResults(ctxArgs, metadata, previous, func(event *output.InternalWrappedEvent) { 176 if event.OperatorsResult != nil && event.OperatorsResult.Matched { 177 matchCount++ 178 } 179 finalEvent = event 180 }) 181 require.Nil(t, err, "could not execute network request") 182 }) 183 184 require.NotNil(t, finalEvent, "could not get event output from request") 185 require.Equal(t, 2, matchCount, "could not get correct match count") 186 }