2021-02-25 23:32:43 +05:30
package main
import (
"errors"
"fmt"
"net/http"
"net/http/httptest"
2021-12-15 16:03:57 +02:00
"net/http/httputil"
2023-02-20 22:26:04 +05:30
"os"
"reflect"
2023-10-20 17:54:10 +05:30
"regexp"
2021-12-15 16:03:57 +02:00
"strconv"
2021-02-25 23:32:43 +05:30
"strings"
2022-08-23 12:45:55 +05:30
"time"
2021-02-25 23:32:43 +05:30
"github.com/julienschmidt/httprouter"
2023-02-20 22:26:04 +05:30
"gopkg.in/yaml.v2"
2021-09-03 16:48:39 +03:00
2023-10-17 17:44:13 +05:30
"github.com/projectdiscovery/nuclei/v3/pkg/testutils"
2025-02-11 04:31:37 +07:00
"github.com/projectdiscovery/nuclei/v3/pkg/utils/json"
2023-03-02 21:21:04 +01:00
"github.com/projectdiscovery/retryablehttp-go"
2025-08-20 05:28:23 +05:30
"github.com/projectdiscovery/utils/errkit"
2023-01-07 13:36:44 +01:00
logutil "github.com/projectdiscovery/utils/log"
2023-03-04 04:57:27 +05:30
sliceutil "github.com/projectdiscovery/utils/slice"
2022-11-14 02:38:12 +02:00
stringsutil "github.com/projectdiscovery/utils/strings"
2024-05-15 15:34:59 +02:00
unitutils "github.com/projectdiscovery/utils/unit"
2021-02-25 23:32:43 +05:30
)
2023-07-28 18:50:57 +03:00
var httpTestcases = [ ] TestCaseInfo {
2023-03-17 16:56:14 +01:00
// TODO: excluded due to parsing errors with console
2023-02-13 12:16:41 +01:00
// "http/raw-unsafe-request.yaml": &httpRawUnsafeRequest{},
2023-08-04 20:21:22 +05:30
{ Path : "protocols/http/get-headers.yaml" , TestCase : & httpGetHeaders { } } ,
{ Path : "protocols/http/get-query-string.yaml" , TestCase : & httpGetQueryString { } } ,
{ Path : "protocols/http/get-redirects.yaml" , TestCase : & httpGetRedirects { } } ,
{ Path : "protocols/http/get-host-redirects.yaml" , TestCase : & httpGetHostRedirects { } } ,
{ Path : "protocols/http/disable-redirects.yaml" , TestCase : & httpDisableRedirects { } } ,
{ Path : "protocols/http/get.yaml" , TestCase : & httpGet { } } ,
{ Path : "protocols/http/post-body.yaml" , TestCase : & httpPostBody { } } ,
{ Path : "protocols/http/post-json-body.yaml" , TestCase : & httpPostJSONBody { } } ,
{ Path : "protocols/http/post-multipart-body.yaml" , TestCase : & httpPostMultipartBody { } } ,
{ Path : "protocols/http/raw-cookie-reuse.yaml" , TestCase : & httpRawCookieReuse { } } ,
{ Path : "protocols/http/raw-dynamic-extractor.yaml" , TestCase : & httpRawDynamicExtractor { } } ,
{ Path : "protocols/http/raw-get-query.yaml" , TestCase : & httpRawGetQuery { } } ,
{ Path : "protocols/http/raw-get.yaml" , TestCase : & httpRawGet { } } ,
{ Path : "protocols/http/raw-with-params.yaml" , TestCase : & httpRawWithParams { } } ,
{ Path : "protocols/http/raw-unsafe-with-params.yaml" , TestCase : & httpRawWithParams { } } , // Not a typo, functionality is same as above
{ Path : "protocols/http/raw-path-trailing-slash.yaml" , TestCase : & httpRawPathTrailingSlash { } } ,
{ Path : "protocols/http/raw-payload.yaml" , TestCase : & httpRawPayload { } } ,
{ Path : "protocols/http/raw-post-body.yaml" , TestCase : & httpRawPostBody { } } ,
{ Path : "protocols/http/raw-unsafe-path.yaml" , TestCase : & httpRawUnsafePath { } } ,
{ Path : "protocols/http/http-paths.yaml" , TestCase : & httpPaths { } } ,
{ Path : "protocols/http/request-condition.yaml" , TestCase : & httpRequestCondition { } } ,
{ Path : "protocols/http/request-condition-new.yaml" , TestCase : & httpRequestCondition { } } ,
{ Path : "protocols/http/self-contained.yaml" , TestCase : & httpRequestSelfContained { } } ,
{ Path : "protocols/http/self-contained-with-path.yaml" , TestCase : & httpRequestSelfContained { } } , // Not a typo, functionality is same as above
{ Path : "protocols/http/self-contained-with-params.yaml" , TestCase : & httpRequestSelfContainedWithParams { } } ,
{ Path : "protocols/http/self-contained-file-input.yaml" , TestCase : & httpRequestSelfContainedFileInput { } } ,
{ Path : "protocols/http/get-case-insensitive.yaml" , TestCase : & httpGetCaseInsensitive { } } ,
{ Path : "protocols/http/get.yaml,protocols/http/get-case-insensitive.yaml" , TestCase : & httpGetCaseInsensitiveCluster { } } ,
{ Path : "protocols/http/get-redirects-chain-headers.yaml" , TestCase : & httpGetRedirectsChainHeaders { } } ,
{ Path : "protocols/http/dsl-matcher-variable.yaml" , TestCase : & httpDSLVariable { } } ,
{ Path : "protocols/http/dsl-functions.yaml" , TestCase : & httpDSLFunctions { } } ,
{ Path : "protocols/http/race-simple.yaml" , TestCase : & httpRaceSimple { } } ,
{ Path : "protocols/http/race-multiple.yaml" , TestCase : & httpRaceMultiple { } } ,
{ Path : "protocols/http/stop-at-first-match.yaml" , TestCase : & httpStopAtFirstMatch { } } ,
{ Path : "protocols/http/stop-at-first-match-with-extractors.yaml" , TestCase : & httpStopAtFirstMatchWithExtractors { } } ,
{ Path : "protocols/http/variables.yaml" , TestCase : & httpVariables { } } ,
{ Path : "protocols/http/variable-dsl-function.yaml" , TestCase : & httpVariableDSLFunction { } } ,
{ Path : "protocols/http/get-override-sni.yaml" , TestCase : & httpSniAnnotation { } } ,
{ Path : "protocols/http/get-sni.yaml" , TestCase : & customCLISNI { } } ,
{ Path : "protocols/http/redirect-match-url.yaml" , TestCase : & httpRedirectMatchURL { } } ,
{ Path : "protocols/http/get-sni-unsafe.yaml" , TestCase : & customCLISNIUnsafe { } } ,
{ Path : "protocols/http/annotation-timeout.yaml" , TestCase : & annotationTimeout { } } ,
{ Path : "protocols/http/custom-attack-type.yaml" , TestCase : & customAttackType { } } ,
{ Path : "protocols/http/get-all-ips.yaml" , TestCase : & scanAllIPS { } } ,
{ Path : "protocols/http/get-without-scheme.yaml" , TestCase : & httpGetWithoutScheme { } } ,
{ Path : "protocols/http/cl-body-without-header.yaml" , TestCase : & httpCLBodyWithoutHeader { } } ,
{ Path : "protocols/http/cl-body-with-header.yaml" , TestCase : & httpCLBodyWithHeader { } } ,
{ Path : "protocols/http/cli-with-constants.yaml" , TestCase : & ConstantWithCliVar { } } ,
{ Path : "protocols/http/matcher-status.yaml" , TestCase : & matcherStatusTest { } } ,
{ Path : "protocols/http/disable-path-automerge.yaml" , TestCase : & httpDisablePathAutomerge { } } ,
2023-10-20 17:54:10 +05:30
{ Path : "protocols/http/http-preprocessor.yaml" , TestCase : & httpPreprocessor { } } ,
{ Path : "protocols/http/multi-request.yaml" , TestCase : & httpMultiRequest { } } ,
2024-03-13 20:35:19 +05:30
{ Path : "protocols/http/http-matcher-extractor-dy-extractor.yaml" , TestCase : & httpMatcherExtractorDynamicExtractor { } } ,
{ Path : "protocols/http/multi-http-var-sharing.yaml" , TestCase : & httpMultiVarSharing { } } ,
2024-04-03 17:09:35 +03:00
{ Path : "protocols/http/raw-path-single-slash.yaml" , TestCase : & httpRawPathSingleSlash { } } ,
{ Path : "protocols/http/raw-unsafe-path-single-slash.yaml" , TestCase : & httpRawUnsafePathSingleSlash { } } ,
2024-03-13 20:35:19 +05:30
}
type httpMultiVarSharing struct { }
func ( h * httpMultiVarSharing ) Execute ( filePath string ) error {
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , "https://scanme.sh" , debug )
if err != nil {
return err
}
return expectResultsCount ( results , 1 )
}
type httpMatcherExtractorDynamicExtractor struct { }
func ( h * httpMatcherExtractorDynamicExtractor ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
html := ` < ! DOCTYPE html >
< html lang = "en" >
< body >
< a href = "/domains" > Domains < / a >
< / body >
< / html > `
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprint ( w , html )
2024-03-13 20:35:19 +05:30
} )
router . GET ( "/domains" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
html := ` < ! DOCTYPE html >
< html lang = "en" >
< head >
< title > Dynamic Extractor Test < / title >
< / head >
< body >
< ! -- The content of the title tag matches the regex pattern for both the extractor and matcher for ' title ' -- >
< / body >
< / html >
`
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprint ( w , html )
2024-03-13 20:35:19 +05:30
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
2021-09-16 21:29:58 +05:30
type httpInteractshRequest struct { }
2021-11-25 17:03:56 +02:00
// Execute executes a test case and returns an error if occurred
2021-09-16 21:29:58 +05:30
func ( h * httpInteractshRequest ) Execute ( filePath string ) error {
router := httprouter . New ( )
2021-11-25 17:18:54 +02:00
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-09-16 21:29:58 +05:30
value := r . Header . Get ( "url" )
if value != "" {
2023-03-02 21:21:04 +01:00
if resp , _ := retryablehttp . DefaultClient ( ) . Get ( value ) ; resp != nil {
2025-07-01 00:40:44 +07:00
_ = resp . Body . Close ( )
2021-09-16 21:29:58 +05:30
}
}
2021-11-25 17:18:54 +02:00
} )
2021-09-16 21:29:58 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-26 16:29:00 +05:30
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-09-16 21:29:58 +05:30
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
2024-11-19 12:38:25 +07:00
return expectResultsCount ( results , 1 , 2 )
2021-09-16 21:29:58 +05:30
}
2023-03-15 20:45:44 +05:30
type httpDefaultMatcherCondition struct { }
// Execute executes a test case and returns an error if occurred
func ( d * httpDefaultMatcherCondition ) Execute ( filePath string ) error {
// to simulate matcher-condition `or`
// - template should be run twice and vulnerable server should send response that fits for that specific run
router := httprouter . New ( )
var routerErr error
// Server endpoint where only interactsh matcher is successful and status code is not 200
router . GET ( "/interactsh/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
value := r . URL . Query ( ) . Get ( "url" )
if value != "" {
if _ , err := retryablehttp . DefaultClient ( ) . Get ( "https://" + value ) ; err != nil {
routerErr = err
}
}
w . WriteHeader ( http . StatusNotFound )
} )
// Server endpoint where url is not probed but sends a 200 status code
router . GET ( "/status/" , func ( w http . ResponseWriter , r * http . Request , p httprouter . Params ) {
w . WriteHeader ( http . StatusOK )
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
2023-03-17 16:56:14 +01:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL + "/status" , debug )
2023-03-15 20:45:44 +05:30
if err != nil {
return err
}
if err := expectResultsCount ( results , 1 ) ; err != nil {
return err
}
2023-03-17 16:56:14 +01:00
results , err = testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL + "/interactsh" , debug )
2023-03-15 20:45:44 +05:30
if err != nil {
return err
}
2023-03-17 16:56:14 +01:00
if routerErr != nil {
2025-08-20 05:28:23 +05:30
return errkit . Append ( errkit . New ( "failed to send http request to interactsh server" ) , routerErr )
2023-03-17 16:56:14 +01:00
}
if err := expectResultsCount ( results , 1 ) ; err != nil {
return err
}
return nil
2023-03-15 20:45:44 +05:30
}
2021-12-21 15:24:16 +05:30
type httpInteractshStopAtFirstMatchRequest struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpInteractshStopAtFirstMatchRequest ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
value := r . Header . Get ( "url" )
if value != "" {
2023-03-02 21:21:04 +01:00
if resp , _ := retryablehttp . DefaultClient ( ) . Get ( value ) ; resp != nil {
2025-07-01 00:40:44 +07:00
_ = resp . Body . Close ( )
2021-12-21 15:24:16 +05:30
}
}
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
2023-08-01 14:33:43 -04:00
// polling is asynchronous, so the interactions may be retrieved after the first request
2021-12-21 15:24:16 +05:30
return expectResultsCount ( results , 1 )
}
2021-02-25 23:32:43 +05:30
type httpGetHeaders struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpGetHeaders ) Execute ( filePath string ) error {
router := httprouter . New ( )
2021-10-01 18:23:06 +03:00
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-25 23:32:43 +05:30
if strings . EqualFold ( r . Header . Get ( "test" ) , "nuclei" ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test headers matcher text" )
2021-02-25 23:32:43 +05:30
}
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
type httpGetQueryString struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpGetQueryString ) Execute ( filePath string ) error {
router := httprouter . New ( )
2021-10-01 18:23:06 +03:00
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-25 23:32:43 +05:30
if strings . EqualFold ( r . URL . Query ( ) . Get ( "test" ) , "nuclei" ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test querystring matcher text" )
2021-02-25 23:32:43 +05:30
}
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
type httpGetRedirects struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpGetRedirects ) Execute ( filePath string ) error {
router := httprouter . New ( )
2021-10-01 18:23:06 +03:00
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-26 13:13:11 +05:30
http . Redirect ( w , r , "/redirected" , http . StatusFound )
2021-10-01 18:23:06 +03:00
} )
router . GET ( "/redirected" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test redirects matcher text" )
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2022-09-29 00:41:28 +02:00
if err != nil {
return err
}
return expectResultsCount ( results , 1 )
}
type httpGetHostRedirects struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpGetHostRedirects ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
http . Redirect ( w , r , "/redirected1" , http . StatusFound )
} )
router . GET ( "/redirected1" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
http . Redirect ( w , r , "redirected2" , http . StatusFound )
} )
router . GET ( "/redirected2" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
http . Redirect ( w , r , "/redirected3" , http . StatusFound )
} )
router . GET ( "/redirected3" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
http . Redirect ( w , r , "https://scanme.sh" , http . StatusTemporaryRedirect )
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
2022-04-27 11:19:44 -05:00
type httpDisableRedirects struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpDisableRedirects ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
http . Redirect ( w , r , "/redirected" , http . StatusMovedPermanently )
} )
router . GET ( "/redirected" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test redirects matcher text" )
2022-04-27 11:19:44 -05:00
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
2022-04-27 11:21:58 -05:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug , "-dr" )
2022-04-27 11:19:44 -05:00
if err != nil {
return err
}
return expectResultsCount ( results , 0 )
}
2021-02-25 23:32:43 +05:30
type httpGet struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpGet ) Execute ( filePath string ) error {
router := httprouter . New ( )
2021-10-01 18:23:06 +03:00
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test matcher text" )
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
2021-11-30 20:20:43 +05:30
type httpDSLVariable struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpDSLVariable ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test matcher text" )
2021-11-30 20:20:43 +05:30
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 5 )
}
type httpDSLFunctions struct { }
func ( h * httpDSLFunctions ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
request , err := httputil . DumpRequest ( r , true )
if err != nil {
_ , _ = fmt . Fprint ( w , err . Error ( ) )
} else {
_ , _ = fmt . Fprint ( w , string ( request ) )
}
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug , "-nc" )
if err != nil {
return err
}
if err := expectResultsCount ( results , 1 ) ; err != nil {
return err
}
2022-11-14 02:38:12 +02:00
// get result part
resultPart , err := stringsutil . After ( results [ 0 ] , ts . URL )
if err != nil {
return err
2021-12-15 16:03:57 +02:00
}
2022-11-14 02:38:12 +02:00
// remove additional characters till the first valid result and ignore last ] which doesn't alter the total count
resultPart = stringsutil . TrimPrefixAny ( resultPart , "/" , " " , "[" )
extracted := strings . Split ( resultPart , "," )
2023-07-14 17:54:12 +02:00
numberOfDslFunctions := 88
2022-11-14 02:38:12 +02:00
if len ( extracted ) != numberOfDslFunctions {
2021-12-15 16:03:57 +02:00
return errors . New ( "incorrect number of results" )
2021-11-30 20:20:43 +05:30
}
2021-12-15 16:03:57 +02:00
2022-11-14 02:38:12 +02:00
for _ , header := range extracted {
2024-01-12 23:10:00 +05:30
header = strings . Trim ( header , ` " ` )
2021-12-15 16:03:57 +02:00
parts := strings . Split ( header , ": " )
index , err := strconv . Atoi ( parts [ 0 ] )
if err != nil {
return err
}
if index < 0 || index > numberOfDslFunctions {
return fmt . Errorf ( "incorrect header index found: %d" , index )
}
if strings . TrimSpace ( parts [ 1 ] ) == "" {
return fmt . Errorf ( "the DSL expression with index %d was not evaluated correctly" , index )
}
}
2021-11-30 20:20:43 +05:30
return nil
}
2021-02-25 23:32:43 +05:30
type httpPostBody struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpPostBody ) Execute ( filePath string ) error {
router := httprouter . New ( )
var routerErr error
2021-10-01 18:23:06 +03:00
router . POST ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-25 23:32:43 +05:30
if err := r . ParseForm ( ) ; err != nil {
routerErr = err
return
}
if strings . EqualFold ( r . Form . Get ( "username" ) , "test" ) && strings . EqualFold ( r . Form . Get ( "password" ) , "nuclei" ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test post-body matcher text" )
2021-02-25 23:32:43 +05:30
}
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
if routerErr != nil {
return routerErr
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
type httpPostJSONBody struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpPostJSONBody ) Execute ( filePath string ) error {
router := httprouter . New ( )
var routerErr error
2021-10-01 18:23:06 +03:00
router . POST ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-25 23:32:43 +05:30
type doc struct {
Username string ` json:"username" `
Password string ` json:"password" `
}
obj := & doc { }
if err := json . NewDecoder ( r . Body ) . Decode ( obj ) ; err != nil {
routerErr = err
return
}
if strings . EqualFold ( obj . Username , "test" ) && strings . EqualFold ( obj . Password , "nuclei" ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test post-json-body matcher text" )
2021-02-25 23:32:43 +05:30
}
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
if routerErr != nil {
return routerErr
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
type httpPostMultipartBody struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpPostMultipartBody ) Execute ( filePath string ) error {
router := httprouter . New ( )
var routerErr error
2021-10-01 18:23:06 +03:00
router . POST ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2024-05-15 15:34:59 +02:00
if err := r . ParseMultipartForm ( unitutils . Mega ) ; err != nil {
2021-02-25 23:32:43 +05:30
routerErr = err
return
}
password , ok := r . MultipartForm . Value [ "password" ]
if ! ok || len ( password ) != 1 {
routerErr = errors . New ( "no password in request" )
return
}
file := r . MultipartForm . File [ "username" ]
if len ( file ) != 1 {
routerErr = errors . New ( "no file in request" )
return
}
if strings . EqualFold ( password [ 0 ] , "nuclei" ) && strings . EqualFold ( file [ 0 ] . Filename , "username" ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test post-multipart matcher text" )
2021-02-25 23:32:43 +05:30
}
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
if routerErr != nil {
return routerErr
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
type httpRawDynamicExtractor struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpRawDynamicExtractor ) Execute ( filePath string ) error {
router := httprouter . New ( )
var routerErr error
2021-10-01 18:23:06 +03:00
router . POST ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-25 23:32:43 +05:30
if err := r . ParseForm ( ) ; err != nil {
routerErr = err
return
}
if strings . EqualFold ( r . Form . Get ( "testing" ) , "parameter" ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "Token: 'nuclei'" )
2021-02-25 23:32:43 +05:30
}
2021-10-01 18:23:06 +03:00
} )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-25 23:32:43 +05:30
if strings . EqualFold ( r . URL . Query ( ) . Get ( "username" ) , "nuclei" ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "Test is test-dynamic-extractor-raw matcher text" )
2021-02-25 23:32:43 +05:30
}
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
if routerErr != nil {
return routerErr
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
type httpRawGetQuery struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpRawGetQuery ) Execute ( filePath string ) error {
router := httprouter . New ( )
2021-10-01 18:23:06 +03:00
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-25 23:32:43 +05:30
if strings . EqualFold ( r . URL . Query ( ) . Get ( "test" ) , "nuclei" ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "Test is test raw-get-query-matcher text" )
2021-02-25 23:32:43 +05:30
}
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
type httpRawGet struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpRawGet ) Execute ( filePath string ) error {
router := httprouter . New ( )
2021-10-01 18:23:06 +03:00
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "Test is test raw-get-matcher text" )
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
2023-05-01 12:15:35 +05:30
type httpRawWithParams struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpRawWithParams ) Execute ( filePath string ) error {
router := httprouter . New ( )
var errx error
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
params := r . URL . Query ( )
// we intentionally use params["test"] instead of params.Get("test") to test the case where
// there are multiple parameters with the same name
if ! reflect . DeepEqual ( params [ "key1" ] , [ ] string { "value1" } ) {
2025-08-20 05:28:23 +05:30
errx = errkit . Append ( errkit . New ( fmt . Sprintf ( "expected %v, got %v" , [ ] string { "value1" } , params [ "key1" ] ) ) , errx )
2023-05-01 12:15:35 +05:30
}
if ! reflect . DeepEqual ( params [ "key2" ] , [ ] string { "value2" } ) {
2025-08-20 05:28:23 +05:30
errx = errkit . Append ( errkit . New ( fmt . Sprintf ( "expected %v, got %v" , [ ] string { "value2" } , params [ "key2" ] ) ) , errx )
2023-05-01 12:15:35 +05:30
}
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "Test is test raw-params-matcher text" )
2023-05-01 12:15:35 +05:30
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL + "/?key1=value1" , debug )
if err != nil {
return err
}
if errx != nil {
return err
}
return expectResultsCount ( results , 1 )
}
2023-01-03 23:45:34 +05:30
type httpRawPathTrailingSlash struct { }
func ( h * httpRawPathTrailingSlash ) Execute ( filepath string ) error {
router := httprouter . New ( )
var routerErr error
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
if r . RequestURI != "/test/..;/..;/" {
routerErr = fmt . Errorf ( "expected path /test/..;/..;/ but got %v" , r . RequestURI )
return
}
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
_ , err := testutils . RunNucleiTemplateAndGetResults ( filepath , ts . URL , debug )
if err != nil {
return err
}
if routerErr != nil {
return routerErr
}
return nil
}
2021-02-25 23:32:43 +05:30
type httpRawPayload struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpRawPayload ) Execute ( filePath string ) error {
router := httprouter . New ( )
var routerErr error
2021-10-01 18:23:06 +03:00
router . POST ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-25 23:32:43 +05:30
if err := r . ParseForm ( ) ; err != nil {
routerErr = err
return
}
2025-07-01 00:40:44 +07:00
if ! strings . EqualFold ( r . Header . Get ( "another_header" ) , "bnVjbGVp" ) && ! strings . EqualFold ( r . Header . Get ( "another_header" ) , "Z3Vlc3Q=" ) {
2021-02-25 23:32:43 +05:30
return
}
if strings . EqualFold ( r . Form . Get ( "username" ) , "test" ) && ( strings . EqualFold ( r . Form . Get ( "password" ) , "nuclei" ) || strings . EqualFold ( r . Form . Get ( "password" ) , "guest" ) ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "Test is raw-payload matcher text" )
2021-02-25 23:32:43 +05:30
}
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
if routerErr != nil {
return routerErr
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 2 )
2021-02-25 23:32:43 +05:30
}
type httpRawPostBody struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpRawPostBody ) Execute ( filePath string ) error {
router := httprouter . New ( )
var routerErr error
2021-10-01 18:23:06 +03:00
router . POST ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-25 23:32:43 +05:30
if err := r . ParseForm ( ) ; err != nil {
routerErr = err
return
}
if strings . EqualFold ( r . Form . Get ( "username" ) , "test" ) && strings . EqualFold ( r . Form . Get ( "password" ) , "nuclei" ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "Test is test raw-post-body-matcher text" )
2021-02-25 23:32:43 +05:30
}
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
if routerErr != nil {
return routerErr
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
2023-02-20 22:26:04 +05:30
type httpRawUnsafePath struct { }
func ( h * httpRawUnsafePath ) Execute ( filepath string ) error {
// testing unsafe paths using router feedback is not possible cause they are `unsafe urls`
// hence it is done by parsing and matching paths from nuclei output with `-debug-req` flag
// read template files
bin , err := os . ReadFile ( filepath )
if err != nil {
return err
}
// Instead of storing expected `paths` in code it is stored in
// `reference` section of template
type template struct {
Info struct {
Reference [ ] string ` yaml:"reference" `
}
}
var tpl template
if err = yaml . Unmarshal ( bin , & tpl ) ; err != nil {
return err
}
// expected relative paths
expected := [ ] string { }
expected = append ( expected , tpl . Info . Reference ... )
if len ( expected ) == 0 {
return fmt . Errorf ( "something went wrong with %v template" , filepath )
}
results , err := testutils . RunNucleiBinaryAndGetCombinedOutput ( debug , [ ] string { "-t" , filepath , "-u" , "scanme.sh" , "-debug-req" } )
if err != nil {
return err
}
actual := [ ] string { }
for _ , v := range strings . Split ( results , "\n" ) {
if strings . Contains ( v , "GET" ) {
parts := strings . Fields ( v )
if len ( parts ) == 3 {
actual = append ( actual , parts [ 1 ] )
}
}
}
if ! reflect . DeepEqual ( expected , actual ) {
return fmt . Errorf ( "%8v: %v\n%-8v: %v" , "expected" , expected , "actual" , actual )
}
return nil
}
type httpPaths struct { }
func ( h * httpPaths ) Execute ( filepath string ) error {
// covers testcases similar to httpRawUnsafePath but when `unsafe:false`
bin , err := os . ReadFile ( filepath )
if err != nil {
return err
}
// Instead of storing expected `paths` in code it is stored in
// `reference` section of template
type template struct {
Info struct {
Reference [ ] string ` yaml:"reference" `
}
}
var tpl template
if err = yaml . Unmarshal ( bin , & tpl ) ; err != nil {
return err
}
// expected relative paths
expected := [ ] string { }
expected = append ( expected , tpl . Info . Reference ... )
if len ( expected ) == 0 {
return fmt . Errorf ( "something went wrong with %v template" , filepath )
}
results , err := testutils . RunNucleiBinaryAndGetCombinedOutput ( debug , [ ] string { "-t" , filepath , "-u" , "scanme.sh" , "-debug-req" } )
if err != nil {
return err
}
actual := [ ] string { }
for _ , v := range strings . Split ( results , "\n" ) {
if strings . Contains ( v , "GET" ) {
parts := strings . Fields ( v )
if len ( parts ) == 3 {
actual = append ( actual , parts [ 1 ] )
}
}
}
2024-03-13 20:35:19 +05:30
if len ( expected ) > len ( actual ) {
2025-06-24 08:19:06 +08:00
actualValuesIndex := max ( len ( actual ) - 1 , 0 )
2024-03-13 20:35:19 +05:30
return fmt . Errorf ( "missing values : %v" , expected [ actualValuesIndex : ] )
} else if len ( expected ) < len ( actual ) {
return fmt . Errorf ( "unexpected values : %v" , actual [ len ( expected ) - 1 : ] )
} else {
if ! reflect . DeepEqual ( expected , actual ) {
return fmt . Errorf ( "expected: %v\n\nactual: %v" , expected , actual )
}
2023-02-20 22:26:04 +05:30
}
return nil
}
2021-02-25 23:32:43 +05:30
type httpRawCookieReuse struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-02-25 23:32:43 +05:30
func ( h * httpRawCookieReuse ) Execute ( filePath string ) error {
router := httprouter . New ( )
var routerErr error
2021-10-01 18:23:06 +03:00
router . POST ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-25 23:32:43 +05:30
if err := r . ParseForm ( ) ; err != nil {
routerErr = err
return
}
if strings . EqualFold ( r . Form . Get ( "testing" ) , "parameter" ) {
http . SetCookie ( w , & http . Cookie { Name : "nuclei" , Value : "test" } )
}
2021-10-01 18:23:06 +03:00
} )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-02-25 23:32:43 +05:30
if err := r . ParseForm ( ) ; err != nil {
routerErr = err
return
}
cookie , err := r . Cookie ( "nuclei" )
if err != nil {
routerErr = err
return
}
if strings . EqualFold ( cookie . Value , "test" ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "Test is test-cookie-reuse matcher text" )
2021-02-25 23:32:43 +05:30
}
2021-10-01 18:23:06 +03:00
} )
2021-02-25 23:32:43 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-02-25 23:32:43 +05:30
if err != nil {
return err
}
if routerErr != nil {
return routerErr
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-02-25 23:32:43 +05:30
}
2023-01-03 08:24:33 +01:00
// TODO: excluded due to parsing errors with console
2022-12-11 18:06:21 +05:30
// type httpRawUnsafeRequest struct{
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2022-12-11 18:06:21 +05:30
// func (h *httpRawUnsafeRequest) Execute(filePath string) error {
// var routerErr error
//
// ts := testutils.NewTCPServer(nil, defaultStaticPort, func(conn net.Conn) {
// defer conn.Close()
2023-06-09 17:24:24 +02:00
// _, _ = conn.Write([]byte("protocols/http/1.1 200 OK\r\nContent-Length: 36\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nThis is test raw-unsafe-matcher test"))
2022-12-11 18:06:21 +05:30
// })
// defer ts.Close()
//
// results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "http://"+ts.URL, debug)
// if err != nil {
// return err
// }
// if routerErr != nil {
// return routerErr
// }
//
// return expectResultsCount(results, 1)
// }
2021-03-09 14:45:04 +05:30
type httpRequestCondition struct { }
2021-09-03 17:25:50 +03:00
// Execute executes a test case and returns an error if occurred
2021-03-09 14:45:04 +05:30
func ( h * httpRequestCondition ) Execute ( filePath string ) error {
router := httprouter . New ( )
2021-10-01 18:23:06 +03:00
router . GET ( "/200" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2023-01-03 08:24:33 +01:00
w . WriteHeader ( http . StatusOK )
2021-10-01 18:23:06 +03:00
} )
router . GET ( "/400" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2023-01-03 08:24:33 +01:00
w . WriteHeader ( http . StatusBadRequest )
2021-10-01 18:23:06 +03:00
} )
2021-03-09 14:45:04 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
2021-10-01 18:23:06 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
2021-03-09 14:45:04 +05:30
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-03-09 14:45:04 +05:30
}
2021-10-19 22:17:44 +05:30
2023-03-04 04:57:27 +05:30
type httpRequestSelfContained struct { }
2021-10-19 22:17:44 +05:30
// Execute executes a test case and returns an error if occurred
2023-03-04 04:57:27 +05:30
func ( h * httpRequestSelfContained ) Execute ( filePath string ) error {
2021-10-19 22:17:44 +05:30
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-10-19 22:20:29 +05:30
_ , _ = w . Write ( [ ] byte ( "This is self-contained response" ) )
2021-10-19 22:17:44 +05:30
} )
server := & http . Server {
2021-10-20 20:13:40 +05:30
Addr : fmt . Sprintf ( "localhost:%d" , defaultStaticPort ) ,
2021-10-19 22:17:44 +05:30
Handler : router ,
}
go func ( ) {
_ = server . ListenAndServe ( )
} ( )
2025-07-01 00:40:44 +07:00
defer func ( ) {
2025-07-09 14:47:26 -05:00
_ = server . Close ( )
} ( )
2021-10-19 22:17:44 +05:30
2024-11-19 19:30:28 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , "" , debug , "-esc" )
2021-10-19 22:17:44 +05:30
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-10-19 22:17:44 +05:30
}
2021-10-29 19:11:57 +03:00
2023-04-26 12:35:07 +05:30
// testcase to check duplicated values in params
type httpRequestSelfContainedWithParams struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpRequestSelfContainedWithParams ) Execute ( filePath string ) error {
router := httprouter . New ( )
2023-05-01 12:15:35 +05:30
var errx error
2023-04-26 12:35:07 +05:30
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
params := r . URL . Query ( )
// we intentionally use params["test"] instead of params.Get("test") to test the case where
// there are multiple parameters with the same name
if ! reflect . DeepEqual ( params [ "something" ] , [ ] string { "here" } ) {
2025-08-20 05:28:23 +05:30
errx = errkit . Append ( errkit . New ( fmt . Sprintf ( "expected %v, got %v" , [ ] string { "here" } , params [ "something" ] ) ) , errx )
2023-04-26 12:35:07 +05:30
}
if ! reflect . DeepEqual ( params [ "key" ] , [ ] string { "value" } ) {
2025-08-20 05:28:23 +05:30
errx = errkit . Append ( errkit . New ( fmt . Sprintf ( "expected %v, got %v" , [ ] string { "value" } , params [ "key" ] ) ) , errx )
2023-04-26 12:35:07 +05:30
}
_ , _ = w . Write ( [ ] byte ( "This is self-contained response" ) )
} )
server := & http . Server {
Addr : fmt . Sprintf ( "localhost:%d" , defaultStaticPort ) ,
Handler : router ,
}
go func ( ) {
_ = server . ListenAndServe ( )
} ( )
2025-07-01 00:40:44 +07:00
defer func ( ) {
2025-07-09 14:47:26 -05:00
_ = server . Close ( )
} ( )
2023-04-26 12:35:07 +05:30
2024-11-19 19:30:28 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , "" , debug , "-esc" )
2023-04-26 12:35:07 +05:30
if err != nil {
return err
}
2023-05-01 12:15:35 +05:30
if errx != nil {
return errx
}
2023-04-26 12:35:07 +05:30
return expectResultsCount ( results , 1 )
}
2023-03-04 04:57:27 +05:30
type httpRequestSelfContainedFileInput struct { }
func ( h * httpRequestSelfContainedFileInput ) Execute ( filePath string ) error {
router := httprouter . New ( )
gotReqToEndpoints := [ ] string { }
router . GET ( "/one" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
gotReqToEndpoints = append ( gotReqToEndpoints , "/one" )
_ , _ = w . Write ( [ ] byte ( "This is self-contained response" ) )
} )
router . GET ( "/two" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
gotReqToEndpoints = append ( gotReqToEndpoints , "/two" )
_ , _ = w . Write ( [ ] byte ( "This is self-contained response" ) )
} )
server := & http . Server {
Addr : fmt . Sprintf ( "localhost:%d" , defaultStaticPort ) ,
Handler : router ,
}
go func ( ) {
_ = server . ListenAndServe ( )
} ( )
2025-07-01 00:40:44 +07:00
defer func ( ) {
2025-07-09 14:47:26 -05:00
_ = server . Close ( )
} ( )
2023-03-04 04:57:27 +05:30
// create temp file
2023-03-14 16:57:48 +01:00
FileLoc , err := os . CreateTemp ( "" , "self-contained-payload-*.txt" )
2023-03-04 04:57:27 +05:30
if err != nil {
2025-08-20 05:28:23 +05:30
return errkit . Append ( errkit . New ( "failed to create temp file" ) , err )
2023-03-04 04:57:27 +05:30
}
2023-03-14 16:57:48 +01:00
if _ , err := FileLoc . Write ( [ ] byte ( "one\ntwo\n" ) ) ; err != nil {
2025-08-20 05:28:23 +05:30
return errkit . Append ( errkit . New ( "failed to write payload to temp file" ) , err )
2023-03-14 16:57:48 +01:00
}
2025-07-01 00:40:44 +07:00
defer func ( ) {
2025-07-09 14:47:26 -05:00
_ = FileLoc . Close ( )
} ( )
2023-03-04 04:57:27 +05:30
2024-11-19 19:30:28 +03:00
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , "" , debug , "-V" , "test=" + FileLoc . Name ( ) , "-esc" )
2023-03-04 04:57:27 +05:30
if err != nil {
return err
}
if err := expectResultsCount ( results , 4 ) ; err != nil {
return err
}
if ! sliceutil . ElementsMatch ( gotReqToEndpoints , [ ] string { "/one" , "/two" , "/one" , "/two" } ) {
2025-08-20 05:28:23 +05:30
return errkit . New ( fmt . Sprintf ( "%s: expected requests to be sent to `/one` and `/two` endpoints but were sent to `%v`" , filePath , gotReqToEndpoints ) ) . Build ( )
2023-03-04 04:57:27 +05:30
}
return nil
}
2021-10-29 19:11:57 +03:00
type httpGetCaseInsensitive struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpGetCaseInsensitive ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "THIS IS TEST MATCHER TEXT" )
2021-10-29 19:11:57 +03:00
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-10-29 19:11:57 +03:00
}
type httpGetCaseInsensitiveCluster struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpGetCaseInsensitiveCluster ) Execute ( filesPath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test matcher text" )
2021-10-29 19:11:57 +03:00
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
files := strings . Split ( filesPath , "," )
results , err := testutils . RunNucleiTemplateAndGetResults ( files [ 0 ] , ts . URL , debug , "-t" , files [ 1 ] )
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 2 )
2021-10-29 19:11:57 +03:00
}
2021-11-09 06:10:07 +05:30
type httpGetRedirectsChainHeaders struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpGetRedirectsChainHeaders ) 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 )
} )
router . GET ( "/redirected" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
w . Header ( ) . Set ( "Secret" , "TestRedirectHeaderMatch" )
http . Redirect ( w , r , "/final" , http . StatusFound )
} )
router . GET ( "/final" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2021-11-09 06:12:36 +05:30
_ , _ = w . Write ( [ ] byte ( "ok" ) )
2021-11-09 06:10:07 +05:30
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
2021-12-15 16:03:57 +02:00
return expectResultsCount ( results , 1 )
2021-11-09 06:10:07 +05:30
}
2022-01-18 14:15:15 +01:00
type httpRaceSimple struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpRaceSimple ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
w . WriteHeader ( http . StatusOK )
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
return expectResultsCount ( results , 10 )
}
type httpRaceMultiple struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpRaceMultiple ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
w . WriteHeader ( http . StatusOK )
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
return expectResultsCount ( results , 5 )
}
2022-02-01 11:25:29 +01:00
type httpStopAtFirstMatch struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpStopAtFirstMatch ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test" )
2022-02-01 11:25:29 +01:00
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
return expectResultsCount ( results , 1 )
}
type httpStopAtFirstMatchWithExtractors struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpStopAtFirstMatchWithExtractors ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test" )
2022-02-01 11:25:29 +01:00
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
return expectResultsCount ( results , 2 )
}
2022-03-30 20:35:46 +05:30
type httpVariables struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpVariables ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "%s\n%s\n%s" , r . Header . Get ( "Test" ) , r . Header . Get ( "Another" ) , r . Header . Get ( "Email" ) )
2022-03-30 20:35:46 +05:30
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
2023-05-02 23:49:56 +05:30
if err := expectResultsCount ( results , 1 ) ; err != nil {
return err
}
2022-03-30 20:35:46 +05:30
2023-05-02 23:49:56 +05:30
// variable override that does not have any match
// to make sure the variable override is working
results , err = testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug , "-var" , "a1=failed" )
if err != nil {
return err
}
return expectResultsCount ( results , 0 )
}
type httpVariableDSLFunction struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpVariableDSLFunction ) Execute ( filePath string ) error {
results , err := testutils . RunNucleiBinaryAndGetCombinedOutput ( debug , [ ] string { "-t" , filePath , "-u" , "https://scanme.sh" , "-debug-req" } )
if err != nil {
return err
}
actual := [ ] string { }
for _ , v := range strings . Split ( results , "\n" ) {
if strings . Contains ( v , "GET" ) {
parts := strings . Fields ( v )
if len ( parts ) == 3 {
actual = append ( actual , parts [ 1 ] )
}
}
}
if len ( actual ) == 2 && actual [ 0 ] == actual [ 1 ] {
return nil
}
return fmt . Errorf ( "expected 2 requests with same URL, got %v" , actual )
2022-03-30 20:35:46 +05:30
}
2022-05-11 12:30:39 +02:00
type customCLISNI struct { }
// Execute executes a test case and returns an error if occurred
func ( h * customCLISNI ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
if r . TLS . ServerName == "test" {
_ , _ = w . Write ( [ ] byte ( "test-ok" ) )
} else {
_ , _ = w . Write ( [ ] byte ( "test-ko" ) )
}
} )
ts := httptest . NewTLSServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug , "-sni" , "test" )
if err != nil {
return err
}
return expectResultsCount ( results , 1 )
}
2022-05-12 13:13:56 +02:00
type httpSniAnnotation struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpSniAnnotation ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
if r . TLS . ServerName == "test" {
_ , _ = w . Write ( [ ] byte ( "test-ok" ) )
} else {
_ , _ = w . Write ( [ ] byte ( "test-ko" ) )
}
} )
ts := httptest . NewTLSServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
return expectResultsCount ( results , 1 )
}
2022-05-27 18:23:07 +02:00
2022-05-30 15:19:09 +05:30
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 ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test redirects matcher text" )
2022-05-30 15:19:09 +05:30
} )
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
}
2022-05-27 18:23:07 +02:00
type customCLISNIUnsafe struct { }
// Execute executes a test case and returns an error if occurred
func ( h * customCLISNIUnsafe ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
if r . TLS . ServerName == "test" {
_ , _ = w . Write ( [ ] byte ( "test-ok" ) )
} else {
_ , _ = w . Write ( [ ] byte ( "test-ko" ) )
}
} )
ts := httptest . NewTLSServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug , "-sni" , "test" )
if err != nil {
return err
}
return expectResultsCount ( results , 1 )
}
2022-08-23 12:45:55 +05:30
type annotationTimeout struct { }
// Execute executes a test case and returns an error if occurred
func ( h * annotationTimeout ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
time . Sleep ( 4 * time . Second )
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test matcher text" )
2022-08-23 12:45:55 +05:30
} )
ts := httptest . NewTLSServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug , "-timeout" , "1" )
if err != nil {
return err
}
return expectResultsCount ( results , 1 )
}
2022-10-19 03:51:45 +05:30
type customAttackType struct { }
// Execute executes a test case and returns an error if occurred
func ( h * customAttackType ) Execute ( filePath string ) error {
router := httprouter . New ( )
got := [ ] string { }
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
got = append ( got , r . URL . RawQuery )
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "This is test custom payload" )
2022-10-19 03:51:45 +05:30
} )
ts := httptest . NewTLSServer ( router )
defer ts . Close ( )
_ , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug , "-attack-type" , "clusterbomb" )
if err != nil {
return err
}
return expectResultsCount ( got , 4 )
}
2022-11-09 14:18:56 +01:00
// Disabled as GH doesn't support ipv6
type scanAllIPS struct { }
// Execute executes a test case and returns an error if occurred
func ( h * scanAllIPS ) Execute ( filePath string ) error {
got , err := testutils . RunNucleiTemplateAndGetResults ( filePath , "https://scanme.sh" , debug , "-scan-all-ips" , "-iv" , "4" )
if err != nil {
return err
}
// limiting test to ipv4 (GH doesn't support ipv6)
return expectResultsCount ( got , 1 )
}
// ensure that ip|host are handled without http|https scheme
type httpGetWithoutScheme struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpGetWithoutScheme ) Execute ( filePath string ) error {
got , err := testutils . RunNucleiTemplateAndGetResults ( filePath , "scanme.sh" , debug )
if err != nil {
return err
}
return expectResultsCount ( got , 1 )
}
2023-01-07 13:36:44 +01:00
// content-length in case the response has no header but has a body
type httpCLBodyWithoutHeader struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpCLBodyWithoutHeader ) Execute ( filePath string ) error {
logutil . DisableDefaultLogger ( )
defer logutil . EnableDefaultLogger ( )
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
w . Header ( ) [ "Content-Length" ] = [ ] string { "-1" }
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "this is a test" )
2023-01-07 13:36:44 +01:00
} )
ts := httptest . NewTLSServer ( router )
defer ts . Close ( )
got , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
return expectResultsCount ( got , 1 )
}
// content-length in case the response has content-length header and a body
type httpCLBodyWithHeader struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpCLBodyWithHeader ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
w . Header ( ) [ "Content-Length" ] = [ ] string { "50000" }
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprintf ( w , "this is a test" )
2023-01-07 13:36:44 +01:00
} )
ts := httptest . NewTLSServer ( router )
defer ts . Close ( )
got , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
return expectResultsCount ( got , 1 )
}
2023-04-26 12:35:07 +05:30
2023-05-25 18:32:35 +02:00
// constant shouldn't be overwritten by cli var with same name
type ConstantWithCliVar struct { }
// Execute executes a test case and returns an error if occurred
func ( h * ConstantWithCliVar ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprint ( w , r . URL . Query ( ) . Get ( "p" ) )
2023-05-25 18:32:35 +02:00
} )
ts := httptest . NewTLSServer ( router )
defer ts . Close ( )
got , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug , "-V" , "test=fromcli" )
if err != nil {
return err
}
return expectResultsCount ( got , 1 )
}
2023-06-19 20:22:17 +05:30
2023-06-30 23:32:00 +05:30
type matcherStatusTest struct { }
// Execute executes a test case and returns an error if occurred
func ( h * matcherStatusTest ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/200" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
w . WriteHeader ( http . StatusOK )
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug , "-ms" )
if err != nil {
return err
}
return expectResultsCount ( results , 1 )
}
2023-06-19 20:22:17 +05:30
// disable path automerge in raw request
type httpDisablePathAutomerge struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpDisablePathAutomerge ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/api/v1/test" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprint ( w , r . URL . Query ( ) . Get ( "id" ) )
2023-06-19 20:22:17 +05:30
} )
2023-08-10 19:28:05 +05:30
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprint ( w , "empty path in raw request" )
2023-08-10 19:28:05 +05:30
} )
2023-06-19 20:22:17 +05:30
ts := httptest . NewServer ( router )
defer ts . Close ( )
got , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL + "/api/v1/user" , debug )
if err != nil {
return err
}
2023-08-10 19:28:05 +05:30
return expectResultsCount ( got , 2 )
2023-06-19 20:22:17 +05:30
}
2023-08-18 02:49:05 +05:30
type httpInteractshRequestsWithMCAnd struct { }
func ( h * httpInteractshRequestsWithMCAnd ) Execute ( filePath string ) error {
got , err := testutils . RunNucleiTemplateAndGetResults ( filePath , "honey.scanme.sh" , debug )
if err != nil {
return err
}
2023-06-19 20:22:17 +05:30
return expectResultsCount ( got , 1 )
}
2023-10-20 17:54:10 +05:30
// integration test to check if preprocessor i.e {{randstr}}
// is working correctly
type httpPreprocessor struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpPreprocessor ) Execute ( filePath string ) error {
router := httprouter . New ( )
re := regexp . MustCompile ( ` [A-Za-z0-9] { 25,} ` )
router . GET ( "/" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
value := r . URL . RequestURI ( )
if re . MatchString ( value ) {
w . WriteHeader ( http . StatusOK )
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprint ( w , "ok" )
2023-10-20 17:54:10 +05:30
} else {
w . WriteHeader ( http . StatusBadRequest )
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprint ( w , "not ok" )
2023-10-20 17:54:10 +05:30
}
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
return expectResultsCount ( results , 1 )
}
type httpMultiRequest struct { }
// Execute executes a test case and returns an error if occurred
func ( h * httpMultiRequest ) Execute ( filePath string ) error {
router := httprouter . New ( )
router . GET ( "/ping" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
w . WriteHeader ( http . StatusOK )
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprint ( w , "ping" )
2023-10-20 17:54:10 +05:30
} )
router . GET ( "/pong" , func ( w http . ResponseWriter , r * http . Request , _ httprouter . Params ) {
w . WriteHeader ( http . StatusOK )
2025-07-01 00:40:44 +07:00
_ , _ = fmt . Fprint ( w , "pong" )
2023-10-20 17:54:10 +05:30
} )
ts := httptest . NewServer ( router )
defer ts . Close ( )
results , err := testutils . RunNucleiTemplateAndGetResults ( filePath , ts . URL , debug )
if err != nil {
return err
}
return expectResultsCount ( results , 1 )
}
2024-04-03 17:09:35 +03:00
type httpRawPathSingleSlash struct { }
func ( h * httpRawPathSingleSlash ) Execute ( filepath string ) error {
expectedPath := "/index.php"
results , err := testutils . RunNucleiBinaryAndGetCombinedOutput ( debug , [ ] string { "-t" , filepath , "-u" , "scanme.sh/index.php" , "-debug-req" } )
if err != nil {
return err
}
var actual string
for _ , v := range strings . Split ( results , "\n" ) {
if strings . Contains ( v , "GET" ) {
parts := strings . Fields ( v )
if len ( parts ) == 3 {
actual = parts [ 1 ]
}
}
}
if actual != expectedPath {
return fmt . Errorf ( "expected: %v\n\nactual: %v" , expectedPath , actual )
}
return nil
}
type httpRawUnsafePathSingleSlash struct { }
func ( h * httpRawUnsafePathSingleSlash ) Execute ( filepath string ) error {
expectedPath := "/index.php"
results , err := testutils . RunNucleiBinaryAndGetCombinedOutput ( debug , [ ] string { "-t" , filepath , "-u" , "scanme.sh/index.php" , "-debug-req" } )
if err != nil {
return err
}
var actual string
for _ , v := range strings . Split ( results , "\n" ) {
if strings . Contains ( v , "GET" ) {
parts := strings . Fields ( v )
if len ( parts ) == 3 {
actual = parts [ 1 ]
}
}
}
if actual != expectedPath {
return fmt . Errorf ( "expected: %v\n\nactual: %v" , expectedPath , actual )
}
return nil
}