Path: blob/dev/cmd/integration-test/headless.go
2070 views
package main12import (3"fmt"4"io"5"net/http"6"net/http/httptest"78"github.com/julienschmidt/httprouter"910"github.com/projectdiscovery/nuclei/v3/pkg/testutils"11)1213var headlessTestcases = []TestCaseInfo{14{Path: "protocols/headless/headless-basic.yaml", TestCase: &headlessBasic{}},15{Path: "protocols/headless/headless-waitevent.yaml", TestCase: &headlessBasic{}},16{Path: "protocols/headless/headless-dsl.yaml", TestCase: &headlessBasic{}},17{Path: "protocols/headless/headless-self-contained.yaml", TestCase: &headlessSelfContained{}},18{Path: "protocols/headless/headless-header-action.yaml", TestCase: &headlessHeaderActions{}},19{Path: "protocols/headless/headless-extract-values.yaml", TestCase: &headlessExtractValues{}},20{Path: "protocols/headless/headless-payloads.yaml", TestCase: &headlessPayloads{}},21{Path: "protocols/headless/variables.yaml", TestCase: &headlessVariables{}},22{Path: "protocols/headless/headless-local.yaml", TestCase: &headlessLocal{}},23{Path: "protocols/headless/file-upload.yaml", TestCase: &headlessFileUpload{}},24{Path: "protocols/headless/file-upload-negative.yaml", TestCase: &headlessFileUploadNegative{}},25{Path: "protocols/headless/headless-header-status-test.yaml", TestCase: &headlessHeaderStatus{}},26}2728type headlessBasic struct{}2930// Execute executes a test case and returns an error if occurred31func (h *headlessBasic) Execute(filePath string) error {32router := httprouter.New()33router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {34_, _ = fmt.Fprintf(w, "<html><body>%s</body></html>", r.URL.Query().Get("_"))35})36ts := httptest.NewServer(router)37defer ts.Close()3839results, err := testutils.RunNucleiTemplateAndGetResults(filePath, ts.URL, debug, "-headless")40if err != nil {41return err42}4344return expectResultsCount(results, 1)45}4647type headlessSelfContained struct{}4849// Execute executes a test case and returns an error if occurred50func (h *headlessSelfContained) Execute(filePath string) error {51results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "", debug, "-headless", "-var query=selfcontained")52if err != nil {53return err54}5556return expectResultsCount(results, 1)57}5859type headlessLocal struct{}6061// Execute executes a test case and returns an error if occurred62// in this testcases local network access is disabled63func (h *headlessLocal) Execute(filePath string) error {64router := httprouter.New()65router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {66_, _ = w.Write([]byte("<html><body></body></html>"))67})68ts := httptest.NewServer(router)69defer ts.Close()7071args := []string{"-t", filePath, "-u", ts.URL, "-headless", "-lna"}7273results, err := testutils.RunNucleiWithArgsAndGetResults(debug, args...)74if err != nil {75return err76}77return expectResultsCount(results, 0)78}7980type headlessHeaderActions struct{}8182// Execute executes a test case and returns an error if occurred83func (h *headlessHeaderActions) Execute(filePath string) error {84router := httprouter.New()85router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {86testValue := r.Header.Get("test")87if r.Header.Get("test") != "" {88_, _ = w.Write([]byte("<html><body>" + testValue + "</body></html>"))89}90})91ts := httptest.NewServer(router)92defer ts.Close()9394results, err := testutils.RunNucleiTemplateAndGetResults(filePath, ts.URL, debug, "-headless")95if err != nil {96return err97}9899return expectResultsCount(results, 1)100}101102type headlessExtractValues struct{}103104// Execute executes a test case and returns an error if occurred105func (h *headlessExtractValues) Execute(filePath string) error {106router := httprouter.New()107router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {108_, _ = w.Write([]byte("<html><body><a href='/test.html'>test</a></body></html>"))109})110ts := httptest.NewServer(router)111defer ts.Close()112results, err := testutils.RunNucleiTemplateAndGetResults(filePath, ts.URL, debug, "-headless")113if err != nil {114return err115}116117return expectResultsCount(results, 1)118}119120type headlessPayloads struct{}121122// Execute executes a test case and returns an error if occurred123func (h *headlessPayloads) Execute(filePath string) error {124router := httprouter.New()125router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {126_, _ = w.Write([]byte("<html><body>test</body></html>"))127})128ts := httptest.NewServer(router)129defer ts.Close()130results, err := testutils.RunNucleiTemplateAndGetResults(filePath, ts.URL, debug, "-headless")131if err != nil {132return err133}134135return expectResultsCount(results, 4)136}137138type headlessVariables struct{}139140// Execute executes a test case and returns an error if occurred141func (h *headlessVariables) Execute(filePath string) error {142router := httprouter.New()143router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {144_, _ = w.Write([]byte("<html><body>aGVsbG8=</body></html>"))145})146ts := httptest.NewServer(router)147defer ts.Close()148results, err := testutils.RunNucleiTemplateAndGetResults(filePath, ts.URL, debug, "-headless")149if err != nil {150return err151}152153return expectResultsCount(results, 1)154}155156type headlessFileUpload struct{}157158// Execute executes a test case and returns an error if occurred159func (h *headlessFileUpload) Execute(filePath string) error {160router := httprouter.New()161router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {162_, _ = w.Write([]byte(`163<!doctype html>164<body>165<form method=post enctype=multipart/form-data>166<input type=file name=file>167<input type=submit value=Upload>168</form>169</body>170</html>171`))172})173router.POST("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {174file, _, err := r.FormFile("file")175if err != nil {176http.Error(w, err.Error(), http.StatusBadRequest)177return178}179180defer func() {181_ = file.Close()182}()183184content, err := io.ReadAll(file)185if err != nil {186http.Error(w, err.Error(), http.StatusBadRequest)187return188}189190_, _ = w.Write(content)191})192ts := httptest.NewServer(router)193defer ts.Close()194195results, err := testutils.RunNucleiTemplateAndGetResults(filePath, ts.URL, debug, "-headless")196if err != nil {197return err198}199200return expectResultsCount(results, 1)201}202203type headlessHeaderStatus struct{}204205// Execute executes a test case and returns an error if occurred206func (h *headlessHeaderStatus) Execute(filePath string) error {207results, err := testutils.RunNucleiTemplateAndGetResults(filePath, "https://scanme.sh", debug, "-headless")208if err != nil {209return err210}211212return expectResultsCount(results, 1)213}214215type headlessFileUploadNegative struct{}216217// Execute executes a test case and returns an error if occurred218func (h *headlessFileUploadNegative) Execute(filePath string) error {219router := httprouter.New()220router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {221_, _ = w.Write([]byte(`222<!doctype html>223<body>224<form method=post enctype=multipart/form-data>225<input type=file name=file>226<input type=submit value=Upload>227</form>228</body>229</html>230`))231})232router.POST("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {233file, _, err := r.FormFile("file")234if err != nil {235http.Error(w, err.Error(), http.StatusBadRequest)236return237}238239defer func() {240_ = file.Close()241}()242243content, err := io.ReadAll(file)244if err != nil {245http.Error(w, err.Error(), http.StatusBadRequest)246return247}248249_, _ = w.Write(content)250})251ts := httptest.NewServer(router)252defer ts.Close()253args := []string{"-t", filePath, "-u", ts.URL, "-headless"}254255results, err := testutils.RunNucleiWithArgsAndGetResults(debug, args...)256if err != nil {257return err258}259return expectResultsCount(results, 0)260}261262263