mirror of https://github.com/daffainfo/nuclei.git
Markdown Export Sorting (#3961)
* Sort markdown exports by host, severity, or template * Switch default to empty string * use fileutil to create folder --------- Co-authored-by: Tarun Koyalwar <tarun@projectdiscovery.io>dev
parent
9558e22a64
commit
759ee3d5f8
|
@ -407,6 +407,13 @@ func readEnvInputVars(options *types.Options) {
|
|||
options.GitLabTemplateDisableDownload = getBoolEnvValue("DISABLE_NUCLEI_TEMPLATES_GITLAB_DOWNLOAD")
|
||||
options.AwsTemplateDisableDownload = getBoolEnvValue("DISABLE_NUCLEI_TEMPLATES_AWS_DOWNLOAD")
|
||||
options.AzureTemplateDisableDownload = getBoolEnvValue("DISABLE_NUCLEI_TEMPLATES_AZURE_DOWNLOAD")
|
||||
|
||||
// Options to modify the behavior of exporters
|
||||
options.MarkdownExportSortMode = strings.ToLower(os.Getenv("MARKDOWN_EXPORT_SORT_MODE"))
|
||||
// If the user has not specified a valid sort mode, use the default
|
||||
if options.MarkdownExportSortMode != "template" && options.MarkdownExportSortMode != "severity" && options.MarkdownExportSortMode != "host" {
|
||||
options.MarkdownExportSortMode = ""
|
||||
}
|
||||
}
|
||||
|
||||
func getBoolEnvValue(key string) bool {
|
||||
|
|
|
@ -346,12 +346,14 @@ func createReportingOptions(options *types.Options) (*reporting.Options, error)
|
|||
reportingOptions.MarkdownExporter = &markdown.Options{
|
||||
Directory: options.MarkdownExportDirectory,
|
||||
IncludeRawPayload: !options.OmitRawRequests,
|
||||
SortMode: options.MarkdownExportSortMode,
|
||||
}
|
||||
} else {
|
||||
reportingOptions = &reporting.Options{}
|
||||
reportingOptions.MarkdownExporter = &markdown.Options{
|
||||
Directory: options.MarkdownExportDirectory,
|
||||
IncludeRawPayload: !options.OmitRawRequests,
|
||||
SortMode: options.MarkdownExportSortMode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,12 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/projectdiscovery/gologger"
|
||||
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/reporting/exporters/markdown/util"
|
||||
"github.com/projectdiscovery/nuclei/v2/pkg/reporting/format"
|
||||
fileutil "github.com/projectdiscovery/utils/file"
|
||||
stringsutil "github.com/projectdiscovery/utils/strings"
|
||||
)
|
||||
|
||||
|
@ -25,6 +28,7 @@ type Options struct {
|
|||
// Directory is the directory to export found results to
|
||||
Directory string `yaml:"directory"`
|
||||
IncludeRawPayload bool `yaml:"include-raw-payload"`
|
||||
SortMode string `yaml:"sort-mode"`
|
||||
}
|
||||
|
||||
// New creates a new markdown exporter integration client based on options.
|
||||
|
@ -69,7 +73,35 @@ func (exporter *Exporter) Export(event *output.ResultEvent) error {
|
|||
defer file.Close()
|
||||
|
||||
filename := createFileName(event)
|
||||
host := util.CreateLink(event.Host, filename)
|
||||
|
||||
// If the sort mode is set to severity, host, or template, then we need to get a safe version of the name for a
|
||||
// subdirectory to store the file in.
|
||||
// This will allow us to sort the files into subdirectories based on the sort mode. The subdirectory will need to
|
||||
// be created if it does not exist.
|
||||
fileUrl := filename
|
||||
subdirectory := ""
|
||||
switch exporter.options.SortMode {
|
||||
case "severity":
|
||||
subdirectory = event.Info.SeverityHolder.Severity.String()
|
||||
case "host":
|
||||
subdirectory = event.Host
|
||||
case "template":
|
||||
subdirectory = event.TemplateID
|
||||
}
|
||||
if subdirectory != "" {
|
||||
// Sanitize the subdirectory name to remove any characters that are not allowed in a directory name
|
||||
subdirectory = sanitizeFilename(subdirectory)
|
||||
|
||||
// Prepend the subdirectory name to the filename for the fileUrl
|
||||
fileUrl = filepath.Join(subdirectory, filename)
|
||||
|
||||
// Create the subdirectory if it does not exist
|
||||
if err = fileutil.CreateFolders(filepath.Join(exporter.directory, subdirectory)); err != nil {
|
||||
gologger.Warning().Msgf("Could not create subdirectory for markdown report: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
host := util.CreateLink(event.Host, fileUrl)
|
||||
finding := event.TemplateID + " " + event.MatcherName
|
||||
severity := event.Info.SeverityHolder.Severity.String()
|
||||
|
||||
|
@ -85,7 +117,7 @@ func (exporter *Exporter) Export(event *output.ResultEvent) error {
|
|||
dataBuilder.WriteString(format.CreateReportDescription(event, util.MarkdownFormatter{}))
|
||||
data := dataBuilder.Bytes()
|
||||
|
||||
return os.WriteFile(filepath.Join(exporter.directory, filename), data, 0644)
|
||||
return os.WriteFile(filepath.Join(exporter.directory, subdirectory, filename), data, 0644)
|
||||
}
|
||||
|
||||
func createFileName(event *output.ResultEvent) string {
|
||||
|
|
|
@ -93,6 +93,8 @@ type Options struct {
|
|||
ReportingConfig string
|
||||
// MarkdownExportDirectory is the directory to export reports in Markdown format
|
||||
MarkdownExportDirectory string
|
||||
// MarkdownExportSortMode is the method to sort the markdown reports (options: severity, template, host, none)
|
||||
MarkdownExportSortMode string
|
||||
// SarifExport is the file to export sarif output format to
|
||||
SarifExport string
|
||||
// CloudURL is the URL for the nuclei cloud endpoint
|
||||
|
|
Loading…
Reference in New Issue