diff --git a/v2/cmd/nuclei/main.go b/v2/cmd/nuclei/main.go index 354f3030f..5a24b8f13 100644 --- a/v2/cmd/nuclei/main.go +++ b/v2/cmd/nuclei/main.go @@ -75,7 +75,7 @@ based on templates offering massive extensibility and ease of use.`) set.BoolVarP(&options.TemplatesVersion, "templates-version", "tv", false, "Shows the installed nuclei-templates version") set.StringVarP(&options.BurpCollaboratorBiid, "burp-collaborator-biid", "biid", "", "Burp Collaborator BIID") set.StringVarP(&options.ReportingConfig, "reporting-config", "rc", "", "Nuclei Reporting Module configuration file") - set.StringVarP(&options.ReportingDirectory, "reporting-directory", "rd", "", "Nuclei Reporting Module cache directory for issue deduplication") + set.StringVarP(&options.ReportingDB, "report-db", "rdb", "", "Local Nuclei Reporting Database") _ = set.Parse() if cfgFile != "" { diff --git a/v2/internal/runner/runner.go b/v2/internal/runner/runner.go index 0815a4797..e5609d209 100644 --- a/v2/internal/runner/runner.go +++ b/v2/internal/runner/runner.go @@ -57,7 +57,7 @@ func New(options *types.Options) (*Runner, error) { runner.catalogue = catalogue.New(runner.options.TemplatesDirectory) if options.ReportingConfig != "" { - if client, err := issues.New(options.ReportingConfig, options.ReportingDirectory); err != nil { + if client, err := issues.New(options.ReportingConfig, options.ReportingDB); err != nil { gologger.Fatal().Msgf("Could not create issue reporting client: %s\n", err) } else { runner.issuesClient = client diff --git a/v2/pkg/reporting/issues/dedupe/dedupe.go b/v2/pkg/reporting/issues/dedupe/dedupe.go index 7df95c2c4..967c06a5d 100644 --- a/v2/pkg/reporting/issues/dedupe/dedupe.go +++ b/v2/pkg/reporting/issues/dedupe/dedupe.go @@ -6,7 +6,8 @@ package dedupe import ( "crypto/sha1" - "path" + "io/ioutil" + "os" "unsafe" "github.com/projectdiscovery/nuclei/v2/pkg/output" @@ -17,33 +18,46 @@ import ( // Storage is a duplicate detecting storage for nuclei scan events. type Storage struct { - storage *leveldb.DB + temporary string + storage *leveldb.DB } const storageFilename = "nuclei-events.db" // New creates a new duplicate detecting storage for nuclei scan events. -func New(folder string) (*Storage, error) { - path := path.Join(folder, storageFilename) +func New(dbPath string) (*Storage, error) { + storage := &Storage{} - db, err := leveldb.OpenFile(path, nil) + var err error + if dbPath == "" { + dbPath, err = ioutil.TempDir("", "nuclei-report-*") + storage.temporary = dbPath + } + if err != nil { + return nil, err + } + + storage.storage, err = leveldb.OpenFile(dbPath, nil) if err != nil { if !errors.IsCorrupted(err) { return nil, err } // If the metadata is corrupted, try to recover - db, err = leveldb.RecoverFile(path, nil) + storage.storage, err = leveldb.RecoverFile(dbPath, nil) if err != nil { return nil, err } } - return &Storage{storage: db}, nil + return storage, nil } // Close closes the storage for further operations func (s *Storage) Close() { s.storage.Close() + if s.temporary != "" { + os.RemoveAll(s.temporary) + } } // Index indexes an item in storage and returns true if the item @@ -75,9 +89,6 @@ func (s *Storage) Index(result *output.ResultEvent) (bool, error) { hasher.Write(unsafeToBytes(k)) hasher.Write(unsafeToBytes(types.ToString(v))) } - if result.Request != "" { - hasher.Write(unsafeToBytes(result.Request)) // Very dumb, change later. - } hash := hasher.Sum(nil) exists, err := s.storage.Has(hash, nil) diff --git a/v2/pkg/reporting/issues/format/format.go b/v2/pkg/reporting/issues/format/format.go index 519554343..ff19cc80a 100644 --- a/v2/pkg/reporting/issues/format/format.go +++ b/v2/pkg/reporting/issues/format/format.go @@ -48,7 +48,7 @@ func MarkdownDescription(output *output.ResultEvent) string { } builder.WriteString("\n**Request**\n\n```\n") builder.WriteString(output.Request) - builder.WriteString("\n```\n\n**Response**\n\n```\n") + builder.WriteString("\n```\n\n
**Response**\n\n```\n") builder.WriteString(output.Response) builder.WriteString("\n```\n\n") diff --git a/v2/pkg/reporting/issues/issues.go b/v2/pkg/reporting/issues/issues.go index 554e11922..ce1af3f41 100644 --- a/v2/pkg/reporting/issues/issues.go +++ b/v2/pkg/reporting/issues/issues.go @@ -35,7 +35,7 @@ type Client struct { } // New creates a new nuclei issue tracker reporting client -func New(config, directory string) (*Client, error) { +func New(config, db string) (*Client, error) { file, err := os.Open(config) if err != nil { return nil, errors.Wrap(err, "could not open reporting config file") @@ -62,7 +62,7 @@ func New(config, directory string) (*Client, error) { if tracker == nil { return nil, errors.New("no issue tracker configuration found") } - storage, err := dedupe.New(directory) + storage, err := dedupe.New(db) if err != nil { return nil, err } diff --git a/v2/pkg/types/types.go b/v2/pkg/types/types.go index 6ccb3b696..fac074efb 100644 --- a/v2/pkg/types/types.go +++ b/v2/pkg/types/types.go @@ -80,9 +80,8 @@ type Options struct { ExcludedTemplates goflags.StringSlice // CustomHeaders is the list of custom global headers to send with each request. CustomHeaders goflags.StringSlice + // ReportingDB is the db for report storage as well as deduplication + ReportingDB string // ReportingConfig is the config file for nuclei reporting module ReportingConfig string - // ReportingDirectory is the directory to store nuclei issue deduplication data - // for reporting in. - ReportingDirectory string }