Added redirected matched URL + stop-at-first-match for redirect chains (#2050)

* Added redirected matched URL + stop-at-first-match for redirect chains

* Pleasing go-linter
dev
Ice3man 2022-05-30 15:19:09 +05:30 committed by GitHub
parent 8723a1fd70
commit be5f1a7623
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 0 deletions

View File

@ -0,0 +1,18 @@
id: redirect-match-url
info:
name: Redirect Match URL
author: pdteam
severity: info
requests:
- method: GET
path:
- "{{BaseURL}}"
stop-at-first-match: true # Confirm stop-at-first-match
redirects: true # Confirm redirected URL matched value
max-redirects: 3
matchers:
- type: word
words:
- "This is test redirects matcher text"

View File

@ -50,6 +50,7 @@ var httpTestcases = map[string]testutils.TestCase{
"http/variables.yaml": &httpVariables{}, "http/variables.yaml": &httpVariables{},
"http/get-override-sni.yaml": &httpSniAnnotation{}, "http/get-override-sni.yaml": &httpSniAnnotation{},
"http/get-sni.yaml": &customCLISNI{}, "http/get-sni.yaml": &customCLISNI{},
"http/redirect-match-url.yaml": &httpRedirectMatchURL{},
"http/get-sni-unsafe.yaml": &customCLISNIUnsafe{}, "http/get-sni-unsafe.yaml": &customCLISNIUnsafe{},
} }
@ -858,6 +859,35 @@ func (h *httpSniAnnotation) Execute(filePath string) error {
return expectResultsCount(results, 1) return expectResultsCount(results, 1)
} }
type httpRedirectMatchURL struct{}
// Execute executes a test case and returns an error if occurred
func (h *httpRedirectMatchURL) Execute(filePath string) error {
router := httprouter.New()
router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
http.Redirect(w, r, "/redirected", http.StatusFound)
_, _ = w.Write([]byte("This is test redirects matcher text"))
})
router.GET("/redirected", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
fmt.Fprintf(w, "This is test redirects matcher text")
})
ts := httptest.NewServer(router)
defer ts.Close()
results, err := testutils.RunNucleiTemplateAndGetResults(filePath, ts.URL, debug, "-no-meta")
if err != nil {
return err
}
if err := expectResultsCount(results, 1); err != nil {
return err
}
if results[0] != fmt.Sprintf("%s/redirected", ts.URL) {
return fmt.Errorf("mismatched url found: %s", results[0])
}
return nil
}
type customCLISNIUnsafe struct{} type customCLISNIUnsafe struct{}
// Execute executes a test case and returns an error if occurred // Execute executes a test case and returns an error if occurred

View File

@ -555,6 +555,12 @@ func (request *Request) executeRequest(reqURL string, generatedRequest *generate
if generatedRequest.request != nil { if generatedRequest.request != nil {
matchedURL = generatedRequest.request.URL.String() matchedURL = generatedRequest.request.URL.String()
} }
// Give precedence to the final URL from response
if response.resp.Request != nil {
if responseURL := response.resp.Request.URL.String(); responseURL != "" {
matchedURL = responseURL
}
}
finalEvent := make(output.InternalEvent) finalEvent := make(output.InternalEvent)
outputEvent := request.responseToDSLMap(response.resp, reqURL, matchedURL, tostring.UnsafeToString(dumpedRequest), tostring.UnsafeToString(response.fullResponse), tostring.UnsafeToString(response.body), tostring.UnsafeToString(response.headers), duration, generatedRequest.meta) outputEvent := request.responseToDSLMap(response.resp, reqURL, matchedURL, tostring.UnsafeToString(dumpedRequest), tostring.UnsafeToString(response.fullResponse), tostring.UnsafeToString(response.body), tostring.UnsafeToString(response.headers), duration, generatedRequest.meta)
@ -598,6 +604,11 @@ func (request *Request) executeRequest(reqURL string, generatedRequest *generate
dumpResponse(event, request, response.fullResponse, formedURL, responseContentType, isResponseTruncated, reqURL) dumpResponse(event, request, response.fullResponse, formedURL, responseContentType, isResponseTruncated, reqURL)
callback(event) callback(event)
// Skip further responses if we have stop-at-first-match and a match
if (request.options.Options.StopAtFirstMatch || request.options.StopAtFirstMatch || request.StopAtFirstMatch) && len(event.Results) > 0 {
return nil
}
} }
return nil return nil
} }