diff --git a/Makefile b/Makefile index 2c27c6fa..352d6341 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -GOTESTWAF_VERSION := $(shell git describe) +GOTESTWAF_VERSION := $(shell git describe --tags) gotestwaf: DOCKER_BUILDKIT=1 docker build --force-rm -t gotestwaf . diff --git a/README.md b/README.md index 10d39b18..de1cbfb6 100644 --- a/README.md +++ b/README.md @@ -363,41 +363,42 @@ Usage: ./gotestwaf [OPTIONS] --url Options: --addDebugHeader Add header with a hash of the test information in each request --addHeader string An HTTP header to add to requests - --blockConnReset If true, connection resets will be considered as block + --blockConnReset If present, connection resets will be considered as block --blockRegex string Regex to detect a blocking page with the same HTTP response status code as a not blocked request --blockStatusCodes ints HTTP status code that WAF uses while blocking requests (default [403]) --configPath string Path to the config file (default "config.yaml") --email string E-mail to which the report will be sent - --followCookies If true, use cookies sent by the server. May work only with --maxIdleConns=1 (gohttp only) + --followCookies If present, use cookies sent by the server. May work only with --maxIdleConns=1 (gohttp only) --graphqlURL string GraphQL URL to check --grpcPort uint16 gRPC port to check - --httpClient string Which HTTP client use to send requests: chrome, gohttp (default "gohttp") + --hideArgsInReport If present, GoTestWAF CLI arguments will not be displayed in the report + --httpClient string Which HTTP client use to send requests: gohttp, chrome (default "gohttp") --idleConnTimeout int The maximum amount of time a keep-alive connection will live (gohttp only) (default 2) - --ignoreUnresolved If true, unresolved test cases will be considered as bypassed (affect score and results) - --includePayloads If true, payloads will be included in HTML/PDF report + --ignoreUnresolved If present, unresolved test cases will be considered as bypassed (affect score and results) + --includePayloads If present, payloads will be included in HTML/PDF report --logFormat string Set logging format: text, json (default "text") --logLevel string Logging level: panic, fatal, error, warn, info, debug, trace (default "info") --maxIdleConns int The maximum number of keep-alive connections (gohttp only) (default 2) --maxRedirects int The maximum number of handling redirects (gohttp only) (default 50) --noEmailReport Save report locally - --nonBlockedAsPassed If true, count requests that weren't blocked as passed. If false, requests that don't satisfy to PassStatusCodes/PassRegExp as blocked + --nonBlockedAsPassed If present, count requests that weren't blocked as passed. If false, requests that don't satisfy to PassStatusCodes/PassRegExp as blocked --openapiFile string Path to openAPI file --passRegex string Regex to a detect normal (not blocked) web page with the same HTTP status code as a blocked request --passStatusCodes ints HTTP response status code that WAF uses while passing requests (default [200,404]) --proxy string Proxy URL to use - --quiet If true, disable verbose logging + --quiet If present, disable verbose logging --randomDelay int Random delay in ms in addition to the delay between requests (default 400) --renewSession Renew cookies before each test. Should be used with --followCookies flag (gohttp only) - --reportFormat string Export report to one of the following formats: none, pdf, html, json (default "pdf") + --reportFormat strings Export report in the following formats: json, html, pdf, none (default [pdf]) --reportName string Report file name. Supports `time' package template format (default "waf-evaluation-report-2006-January-02-15-04-05") --reportPath string A directory to store reports (default "reports") --sendDelay int Delay in ms between requests (default 400) - --skipWAFBlockCheck If true, WAF detection tests will be skipped + --skipWAFBlockCheck If present, WAF detection tests will be skipped --skipWAFIdentification Skip WAF identification --testCase string If set then only this test case will be run --testCasesPath string Path to a folder with test cases (default "testcases") --testSet string If set then only this test set's cases will be run - --tlsVerify If true, the received TLS certificate will be verified + --tlsVerify If present, the received TLS certificate will be verified --url string URL to check --version Show GoTestWAF version and exit --wafName string Name of the WAF product (default "generic") diff --git a/cmd/gotestwaf/flags.go b/cmd/gotestwaf/flags.go index 3e93a7c1..3ccb4802 100644 --- a/cmd/gotestwaf/flags.go +++ b/cmd/gotestwaf/flags.go @@ -93,7 +93,7 @@ func parseFlags() (args []string, err error) { // General parameters flag.StringVar(&configPath, "configPath", defaultConfigPath, "Path to the config file") - flag.BoolVar(&quiet, "quiet", false, "If true, disable verbose logging") + flag.BoolVar(&quiet, "quiet", false, "If present, disable verbose logging") logLvl := flag.String("logLevel", "info", "Logging level: panic, fatal, error, warn, info, debug, trace") flag.StringVar(&logFormat, "logFormat", textLogFormat, "Set logging format: "+strings.Join(logFormats, ", ")) showVersion := flag.Bool("version", false, "Show GoTestWAF version and exit") @@ -111,7 +111,7 @@ func parseFlags() (args []string, err error) { // HTTP client settings httpClient := flag.String("httpClient", gohttpClient, "Which HTTP client use to send requests: "+strings.Join(httpClients, ", ")) - flag.Bool("tlsVerify", false, "If true, the received TLS certificate will be verified") + flag.Bool("tlsVerify", false, "If present, the received TLS certificate will be verified") flag.String("proxy", "", "Proxy URL to use") flag.String("addHeader", "", "An HTTP header to add to requests") flag.Bool("addDebugHeader", false, "Add header with a hash of the test information in each request") @@ -120,7 +120,7 @@ func parseFlags() (args []string, err error) { flag.Int("maxIdleConns", 2, "The maximum number of keep-alive connections (gohttp only)") flag.Int("maxRedirects", 50, "The maximum number of handling redirects (gohttp only)") flag.Int("idleConnTimeout", 2, "The maximum amount of time a keep-alive connection will live (gohttp only)") - flag.Bool("followCookies", false, "If true, use cookies sent by the server. May work only with --maxIdleConns=1 (gohttp only)") + flag.Bool("followCookies", false, "If present, use cookies sent by the server. May work only with --maxIdleConns=1 (gohttp only)") flag.Bool("renewSession", false, "Renew cookies before each test. Should be used with --followCookies flag (gohttp only)") // Performance settings @@ -129,7 +129,7 @@ func parseFlags() (args []string, err error) { flag.Int("randomDelay", 400, "Random delay in ms in addition to the delay between requests") // Analysis settings - flag.Bool("skipWAFBlockCheck", false, "If true, WAF detection tests will be skipped") + flag.Bool("skipWAFBlockCheck", false, "If present, WAF detection tests will be skipped") flag.Bool("skipWAFIdentification", false, "Skip WAF identification") flag.IntSlice("blockStatusCodes", []int{403}, "HTTP status code that WAF uses while blocking requests") flag.IntSlice("passStatusCodes", []int{200, 404}, "HTTP response status code that WAF uses while passing requests") @@ -138,18 +138,19 @@ func parseFlags() (args []string, err error) { passRegex := flag.String("passRegex", "", "Regex to a detect normal (not blocked) web page with the same HTTP status code as a blocked request") flag.Bool("nonBlockedAsPassed", false, - "If true, count requests that weren't blocked as passed. If false, requests that don't satisfy to PassStatusCodes/PassRegExp as blocked") - flag.Bool("ignoreUnresolved", false, "If true, unresolved test cases will be considered as bypassed (affect score and results)") - flag.Bool("blockConnReset", false, "If true, connection resets will be considered as block") + "If present, count requests that weren't blocked as passed. If false, requests that don't satisfy to PassStatusCodes/PassRegExp as blocked") + flag.Bool("ignoreUnresolved", false, "If present, unresolved test cases will be considered as bypassed (affect score and results)") + flag.Bool("blockConnReset", false, "If present, connection resets will be considered as block") // Report settings flag.String("wafName", wafName, "Name of the WAF product") - flag.Bool("includePayloads", false, "If true, payloads will be included in HTML/PDF report") + flag.Bool("includePayloads", false, "If present, payloads will be included in HTML/PDF report") flag.String("reportPath", reportPath, "A directory to store reports") reportName := flag.String("reportName", defaultReportName, "Report file name. Supports `time' package template format") reportFormat := flag.StringSlice("reportFormat", []string{report.PdfFormat}, "Export report in the following formats: "+strings.Join(report.ReportFormats, ", ")) noEmailReport := flag.Bool("noEmailReport", false, "Save report locally") email := flag.String("email", "", "E-mail to which the report will be sent") + flag.Bool("hideArgsInReport", false, "If present, GoTestWAF CLI arguments will not be displayed in the report") flag.Parse() diff --git a/cmd/gotestwaf/main.go b/cmd/gotestwaf/main.go index 8a7c06e1..97803e8d 100644 --- a/cmd/gotestwaf/main.go +++ b/cmd/gotestwaf/main.go @@ -61,7 +61,10 @@ func main() { logger.WithError(err).Error("couldn't load config") os.Exit(1) } - cfg.Args = args + + if !cfg.HideArgsInReport { + cfg.Args = args + } if err := run(ctx, cfg, logger); err != nil { logger.WithError(err).Error("caught error in main function") diff --git a/internal/config/config.go b/internal/config/config.go index 5ffcae0a..cc38814b 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -47,13 +47,14 @@ type Config struct { BlockConnReset bool `mapstructure:"blockConnReset"` // Report settings - WAFName string `mapstructure:"wafName"` - IncludePayloads bool `mapstructure:"includePayloads"` - ReportPath string `mapstructure:"reportPath"` - ReportName string `mapstructure:"reportName"` - ReportFormat []string `mapstructure:"reportFormat"` - NoEmailReport bool `mapstructure:"noEmailReport"` - Email string `mapstructure:"email"` + WAFName string `mapstructure:"wafName"` + IncludePayloads bool `mapstructure:"includePayloads"` + ReportPath string `mapstructure:"reportPath"` + ReportName string `mapstructure:"reportName"` + ReportFormat []string `mapstructure:"reportFormat"` + NoEmailReport bool `mapstructure:"noEmailReport"` + Email string `mapstructure:"email"` + HideArgsInReport bool `mapstructure:"hideArgsInReport"` // config.yaml HTTPHeaders map[string]string `mapstructure:"headers"` diff --git a/pkg/report/html.go b/pkg/report/html.go index e87f0240..6b25c26d 100644 --- a/pkg/report/html.go +++ b/pkg/report/html.go @@ -26,7 +26,7 @@ type HtmlReport struct { GtwVersion string `json:"gtw_version" validate:"required,gtw_version"` TestCasesFP string `json:"test_cases_fp" validate:"required,fp"` OpenApiFile string `json:"open_api_file" validate:"omitempty,printascii,max=512"` - Args []string `json:"args" validate:"required,max=50,dive,args,max=200"` + Args []string `json:"args" validate:"omitempty,max=50,dive,args,max=200"` ApiSecChartData struct { Indicators []string `json:"indicators" validate:"omitempty,max=100,dive,indicator"` diff --git a/pkg/report/report_template.html b/pkg/report/report_template.html index 0a8449f4..69b0ac41 100644 --- a/pkg/report/report_template.html +++ b/pkg/report/report_template.html @@ -399,10 +399,12 @@

Overall grade:

{{.OpenApiFile}}
{{end}} + {{$length := len $.Args}}{{if ne $length 0}} Used arguments : {{StringsJoin .Args " "}}
+ {{end}}