diff --git a/Makefile b/Makefile index bfb0b5a64..d0d995bfc 100644 --- a/Makefile +++ b/Makefile @@ -147,8 +147,6 @@ template-validate: build template-validate: ./bin/nuclei -ut ./bin/nuclei -validate \ - -et .github/ \ - -et helpers/payloads/ \ -et http/technologies \ -t dns \ -t ssl \ @@ -157,7 +155,5 @@ template-validate: -ept code ./bin/nuclei -validate \ -w workflows \ - -et .github/ \ - -et helpers/payloads/ \ -et http/technologies \ -ept code \ No newline at end of file diff --git a/pkg/catalog/config/template.go b/pkg/catalog/config/template.go index 3d7b33de5..2f7999184 100644 --- a/pkg/catalog/config/template.go +++ b/pkg/catalog/config/template.go @@ -12,7 +12,10 @@ import ( stringsutil "github.com/projectdiscovery/utils/strings" ) -var knownConfigFiles = []string{"cves.json", "contributors.json", "TEMPLATES-STATS.json"} +var ( + knownConfigFiles = []string{"cves.json", "contributors.json", "TEMPLATES-STATS.json"} + knownMiscDirectories = []string{".git", ".github", "helpers"} +) // TemplateFormat type TemplateFormat uint8 @@ -23,6 +26,25 @@ const ( Unknown ) +// GetKnownConfigFiles returns known config files. +func GetKnownConfigFiles() []string { + return knownConfigFiles +} + +// GetKnownMiscDirectories returns known misc directories with trailing slashes. +// +// The trailing slash ensures that directory matching is explicit and avoids +// falsely match files with similar names (e.g. "helpers" matching +// "some-helpers.yaml"), since [IsTemplate] checks against normalized full paths. +func GetKnownMiscDirectories() []string { + trailedSlashDirs := make([]string, 0, len(knownMiscDirectories)) + for _, dir := range knownMiscDirectories { + trailedSlashDirs = append(trailedSlashDirs, dir+string(os.PathSeparator)) + } + + return trailedSlashDirs +} + // GetTemplateFormatFromExt returns template format func GetTemplateFormatFromExt(filePath string) TemplateFormat { fileExt := strings.ToLower(filepath.Ext(filePath)) @@ -41,13 +63,22 @@ func GetSupportTemplateFileExtensions() []string { return []string{extensions.YAML, extensions.JSON} } -// IsTemplate is a callback function used by goflags to decide if given file should be read -// if it is not a nuclei-template file only then file is read -func IsTemplate(filename string) bool { - if stringsutil.ContainsAny(filename, knownConfigFiles...) { +// IsTemplate returns true if the file is a template based on its path. +// It used by goflags and other places to filter out non-template files. +func IsTemplate(fpath string) bool { + fpath = filepath.FromSlash(fpath) + fname := filepath.Base(fpath) + fext := strings.ToLower(filepath.Ext(fpath)) + + if stringsutil.ContainsAny(fname, GetKnownConfigFiles()...) { return false } - return stringsutil.EqualFoldAny(filepath.Ext(filename), GetSupportTemplateFileExtensions()...) + + if stringsutil.ContainsAny(fpath, GetKnownMiscDirectories()...) { + return false + } + + return stringsutil.EqualFoldAny(fext, GetSupportTemplateFileExtensions()...) } type template struct { diff --git a/pkg/catalog/disk/find.go b/pkg/catalog/disk/find.go index 7a70c1bc1..0a89ba54c 100644 --- a/pkg/catalog/disk/find.go +++ b/pkg/catalog/disk/find.go @@ -257,7 +257,7 @@ func (c *DiskCatalog) findDirectoryMatches(absPath string, processed map[string] if err != nil { return nil } - if !d.IsDir() && config.GetTemplateFormatFromExt(path) != config.Unknown { + if !d.IsDir() && config.IsTemplate(path) { if _, ok := processed[path]; !ok { results = append(results, path) processed[path] = struct{}{} @@ -281,7 +281,7 @@ func (c *DiskCatalog) findDirectoryMatches(absPath string, processed map[string] if err != nil { return nil } - if !d.IsDir() && config.GetTemplateFormatFromExt(path) != config.Unknown { + if !d.IsDir() && config.IsTemplate(path) { if _, ok := processed[path]; !ok { results = append(results, path) processed[path] = struct{}{} diff --git a/pkg/templates/workflows.go b/pkg/templates/workflows.go index 50029af18..2f1881cbe 100644 --- a/pkg/templates/workflows.go +++ b/pkg/templates/workflows.go @@ -94,7 +94,14 @@ func parseWorkflowTemplate(workflow *workflows.WorkflowTemplate, preprocessor Pr if len(template.RequestsCode) > 0 { if !options.Options.EnableCodeTemplates { - gologger.Warning().Msgf("`-code` flag not found, skipping code template from workflow: %v\n", path) + // NOTE(dwisiswant0): It is safe to continue here during + // validation mode, because the template has already been parsed + // and syntax-validated by templates.Parse() above. It only + // prevents adding to workflow's executer list and suppresses + // warning messages. + if !options.Options.Validate { + gologger.Warning().Msgf("`-code` flag not found, skipping code template from workflow: %v\n", path) + } continue } else if !template.Verified { // unverfied code templates are not allowed in workflows