Skip to content

Commit

Permalink
Merge pull request #616 from projectdiscovery/exclude-tags
Browse files Browse the repository at this point in the history
Added exclude-tag flags
  • Loading branch information
Ice3man543 committed Mar 13, 2021
2 parents 15111ec + 35402d6 commit 266e332
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 18 deletions.
1 change: 1 addition & 0 deletions v2/cmd/nuclei/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ based on templates offering massive extensibility and ease of use.`)
set.StringVarP(&options.ReportingConfig, "report-config", "rc", "", "Nuclei Reporting Module configuration file")
set.StringVarP(&options.ReportingDB, "report-db", "rdb", "", "Local Nuclei Reporting Database")
set.StringSliceVar(&options.Tags, "tags", []string{}, "Tags to execute templates for")
set.StringSliceVarP(&options.ExcludeTags, "exclude-tags", "etags", []string{}, "Exclude templates with the provided tags")
set.StringVarP(&options.ResolversFile, "resolvers", "r", "", "File containing resolver list for nuclei")
set.BoolVar(&options.Headless, "headless", false, "Enable headless browser based templates support")
set.BoolVar(&options.ShowBrowser, "show-browser", false, "Show the browser on the screen")
Expand Down
1 change: 1 addition & 0 deletions v2/internal/runner/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func ParseOptions(options *types.Options) {
// Show the user the banner
showBanner()

options.ExcludeTags = append(options.ExcludeTags, "dos")
if options.Version {
gologger.Info().Msgf("Current Version: %s\n", Version)
os.Exit(0)
Expand Down
4 changes: 2 additions & 2 deletions v2/internal/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ func (r *Runner) Close() {
// RunEnumeration sets up the input layer for giving input nuclei.
// binary and runs the actual enumeration
func (r *Runner) RunEnumeration() {
// resolves input templates definitions and any optional exclusion
if len(r.options.Templates) == 0 && len(r.options.Tags) > 0 {
// If we have no templates, run on whole template directory with provided tags
if len(r.options.Templates) == 0 && (len(r.options.Tags) > 0 || len(r.options.ExcludeTags) > 0) {
r.options.Templates = append(r.options.Templates, r.options.TemplatesDirectory)
}
if r.options.NewTemplates {
Expand Down
21 changes: 14 additions & 7 deletions v2/pkg/templates/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,20 @@ func Parse(filePath string, options protocols.ExecuterOptions) (*Template, error
if _, ok := template.Info["author"]; !ok {
return nil, errors.New("no template author field provided")
}
templateTags, ok := template.Info["tags"]
if !ok {
templateTags = ""
}
matchWithTags := false
if len(options.Options.Tags) > 0 {
templateTags, ok := template.Info["tags"]
if !ok {
templateTags = ""
if err := matchTemplateWithTags(types.ToString(templateTags), types.ToString(template.Info["severity"]), options.Options.Tags); err != nil {
return nil, fmt.Errorf("tags filter not matched %s", templateTags)
}
if err := matchTemplateWithTags(types.ToString(templateTags), types.ToString(template.Info["severity"]), options.Options); err != nil {
return nil, nil
matchWithTags = true
}
if len(options.Options.ExcludeTags) > 0 && !matchWithTags {
if err := matchTemplateWithTags(types.ToString(templateTags), types.ToString(template.Info["severity"]), options.Options.ExcludeTags); err == nil {
return nil, fmt.Errorf("exclude-tags filter matched %s", templateTags)
}
}

Expand Down Expand Up @@ -200,15 +207,15 @@ func (t *Template) parseWorkflowTemplate(workflow *workflows.WorkflowTemplate, o
}

// matchTemplateWithTags matches if the template matches a tag
func matchTemplateWithTags(tags, severity string, options *types.Options) error {
func matchTemplateWithTags(tags, severity string, tagsInput []string) error {
actualTags := strings.Split(tags, ",")
if severity != "" {
actualTags = append(actualTags, severity) // also add severity to tag
}

matched := false
mainLoop:
for _, t := range options.Tags {
for _, t := range tagsInput {
commaTags := strings.Split(t, ",")
for _, tag := range commaTags {
tag = strings.TrimSpace(tag)
Expand Down
17 changes: 8 additions & 9 deletions v2/pkg/templates/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,39 @@ package templates
import (
"testing"

"github.com/projectdiscovery/nuclei/v2/pkg/types"
"github.com/stretchr/testify/require"
)

func TestMatchTemplateWithTags(t *testing.T) {
err := matchTemplateWithTags("php,linux,symfony", "", &types.Options{Tags: []string{"php"}})
err := matchTemplateWithTags("php,linux,symfony", "", []string{"php"})
require.Nil(t, err, "could not get php tag from input slice")

err = matchTemplateWithTags("lang:php,os:linux,cms:symfony", "", &types.Options{Tags: []string{"cms:symfony"}})
err = matchTemplateWithTags("lang:php,os:linux,cms:symfony", "", []string{"cms:symfony"})
require.Nil(t, err, "could not get php tag from input key value")

err = matchTemplateWithTags("lang:php,os:linux,symfony", "", &types.Options{Tags: []string{"cms:symfony"}})
err = matchTemplateWithTags("lang:php,os:linux,symfony", "", []string{"cms:symfony"})
require.NotNil(t, err, "could get key value tag from input key value")

err = matchTemplateWithTags("lang:php,os:linux,cms:jira", "", &types.Options{Tags: []string{"cms:symfony"}})
err = matchTemplateWithTags("lang:php,os:linux,cms:jira", "", []string{"cms:symfony"})
require.NotNil(t, err, "could get key value tag from input key value")

t.Run("space", func(t *testing.T) {
err = matchTemplateWithTags("lang:php, os:linux, cms:symfony", "", &types.Options{Tags: []string{"cms:symfony"}})
err = matchTemplateWithTags("lang:php, os:linux, cms:symfony", "", []string{"cms:symfony"})
require.Nil(t, err, "could get key value tag from input key value with space")
})

t.Run("comma-tags", func(t *testing.T) {
err = matchTemplateWithTags("lang:php,os:linux,cms:symfony", "", &types.Options{Tags: []string{"test,cms:symfony"}})
err = matchTemplateWithTags("lang:php,os:linux,cms:symfony", "", []string{"test,cms:symfony"})
require.Nil(t, err, "could get key value tag from input key value with comma")
})

t.Run("severity", func(t *testing.T) {
err = matchTemplateWithTags("lang:php,os:linux,cms:symfony", "low", &types.Options{Tags: []string{"low"}})
err = matchTemplateWithTags("lang:php,os:linux,cms:symfony", "low", []string{"low"})
require.Nil(t, err, "could get key value tag for severity")
})

t.Run("blank-tags", func(t *testing.T) {
err = matchTemplateWithTags("", "low", &types.Options{Tags: []string{"jira"}})
err = matchTemplateWithTags("", "low", []string{"jira"})
require.NotNil(t, err, "could get value tag for blank severity")
})
}
2 changes: 2 additions & 0 deletions v2/pkg/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ type Options struct {
// can be specified with -l flag and -tags can be used in combination with
// the -l flag.
Tags goflags.StringSlice
// ExcludeTags is the list of tags to exclude
ExcludeTags goflags.StringSlice
// Workflows specifies any workflows to run by nuclei
Workflows goflags.StringSlice
// Templates specifies the template/templates to use
Expand Down

0 comments on commit 266e332

Please sign in to comment.