Add exclude severity filter

dev
Alexey Zhuchkov 2021-10-08 22:24:29 +03:00
parent c4b69f5991
commit 3e8a0af36f
6 changed files with 60 additions and 30 deletions

View File

@ -71,6 +71,7 @@ on extensive configurability, massive extensibility and ease of use.`)
flagSet.StringSliceVarP(&options.ExcludedTemplates, "exclude", "exclude-templates", []string{}, "template or template directory paths to exclude"),
flagSet.VarP(&options.Severities, "impact", "severity", fmt.Sprintf("Templates to run based on severity. Possible values: %s", severity.GetSupportedSeverities().String())),
flagSet.VarP(&options.ExcludeSeverities, "exclude-impact", "exclude-severity", fmt.Sprintf("Templates to exclude based on severity. Possible values: %s", severity.GetSupportedSeverities().String())),
flagSet.NormalizedStringSliceVar(&options.Author, "author", []string{}, "execute templates that are (co-)created by the specified authors"),
)

View File

@ -344,6 +344,7 @@ func (r *Runner) RunEnumeration() error {
IncludeTemplates: r.options.IncludeTemplates,
Authors: r.options.Author,
Severities: r.options.Severities,
ExcludeSeverities: r.options.ExcludeSeverities,
IncludeTags: r.options.IncludeTags,
TemplatesDirectory: r.options.TemplatesDirectory,
Catalog: r.catalog,

View File

@ -9,11 +9,12 @@ import (
// TagFilter is used to filter nuclei templates for tag based execution
type TagFilter struct {
allowedTags map[string]struct{}
severities map[severity.Severity]struct{}
authors map[string]struct{}
block map[string]struct{}
matchAllows map[string]struct{}
allowedTags map[string]struct{}
severities map[severity.Severity]struct{}
excludeSeverities map[severity.Severity]struct{}
authors map[string]struct{}
block map[string]struct{}
matchAllows map[string]struct{}
}
// ErrExcluded is returned for excluded templates
@ -54,15 +55,21 @@ func (tagFilter *TagFilter) Match(templateTags, templateAuthors []string, templa
}
func isSeverityMatch(tagFilter *TagFilter, templateSeverity severity.Severity) bool {
if len(tagFilter.severities) == 0 || templateSeverity == severity.Undefined {
if (len(tagFilter.excludeSeverities) == 0 && len(tagFilter.severities) == 0) || templateSeverity == severity.Undefined {
return true
}
if _, ok := tagFilter.severities[templateSeverity]; ok {
return true
included := true
if len(tagFilter.severities) > 0 {
_, included = tagFilter.severities[templateSeverity]
}
return false
excluded := false
if len(tagFilter.excludeSeverities) > 0 {
_, excluded = tagFilter.excludeSeverities[templateSeverity]
}
return included && !excluded
}
func isAuthorMatch(tagFilter *TagFilter, templateAuthors []string) bool {
@ -110,23 +117,25 @@ func isTagMatch(tagFilter *TagFilter, templateTags []string) bool {
}
type Config struct {
Tags []string
ExcludeTags []string
Authors []string
Severities severity.Severities
IncludeTags []string
Tags []string
ExcludeTags []string
Authors []string
Severities severity.Severities
ExcludeSeverities severity.Severities
IncludeTags []string
}
// New returns a tag filter for nuclei tag based execution
//
// It takes into account Tags, Severities, Authors, IncludeTags, ExcludeTags.
// It takes into account Tags, Severities, ExcludeSeverities, Authors, IncludeTags, ExcludeTags.
func New(config *Config) *TagFilter {
filter := &TagFilter{
allowedTags: make(map[string]struct{}),
authors: make(map[string]struct{}),
severities: make(map[severity.Severity]struct{}),
block: make(map[string]struct{}),
matchAllows: make(map[string]struct{}),
allowedTags: make(map[string]struct{}),
authors: make(map[string]struct{}),
severities: make(map[severity.Severity]struct{}),
excludeSeverities: make(map[severity.Severity]struct{}),
block: make(map[string]struct{}),
matchAllows: make(map[string]struct{}),
}
for _, tag := range config.ExcludeTags {
for _, val := range splitCommaTrim(tag) {
@ -140,6 +149,11 @@ func New(config *Config) *TagFilter {
filter.severities[tag] = struct{}{}
}
}
for _, tag := range config.ExcludeSeverities {
if _, ok := filter.excludeSeverities[tag]; !ok {
filter.excludeSeverities[tag] = struct{}{}
}
}
for _, tag := range config.Authors {
for _, val := range splitCommaTrim(tag) {
if _, ok := filter.authors[val]; !ok {

View File

@ -73,6 +73,16 @@ func TestTagBasedFilter(t *testing.T) {
matched, _ := filter.Match([]string{"fuzz"}, []string{"pdteam"}, severity.High, nil)
require.True(t, matched, "could not get correct match")
})
t.Run("match-exclude-severity", func(t *testing.T) {
filter := New(&Config{
ExcludeSeverities: severity.Severities{severity.Low},
})
matched, _ := filter.Match([]string{"fuzz"}, []string{"pdteam"}, severity.High, nil)
require.True(t, matched, "could not get correct match")
matched, _ = filter.Match([]string{"fuzz"}, []string{"pdteam"}, severity.Low, nil)
require.False(t, matched, "could not get correct match")
})
t.Run("match-exclude-with-tags", func(t *testing.T) {
filter := New(&Config{
Tags: []string{"tag"},

View File

@ -19,11 +19,12 @@ type Config struct {
ExcludeTemplates []string
IncludeTemplates []string
Tags []string
ExcludeTags []string
Authors []string
Severities severity.Severities
IncludeTags []string
Tags []string
ExcludeTags []string
Authors []string
Severities severity.Severities
ExcludeSeverities severity.Severities
IncludeTags []string
Catalog *catalog.Catalog
ExecutorOptions protocols.ExecuterOptions
@ -49,11 +50,12 @@ func New(config *Config) (*Store, error) {
store := &Store{
config: config,
tagFilter: filter.New(&filter.Config{
Tags: config.Tags,
ExcludeTags: config.ExcludeTags,
Authors: config.Authors,
Severities: config.Severities,
IncludeTags: config.IncludeTags,
Tags: config.Tags,
ExcludeTags: config.ExcludeTags,
Authors: config.Authors,
Severities: config.Severities,
ExcludeSeverities: config.ExcludeSeverities,
IncludeTags: config.IncludeTags,
}),
pathFilter: filter.NewPathFilter(&filter.PathFilterConfig{
IncludedTemplates: config.IncludeTemplates,

View File

@ -25,6 +25,8 @@ type Options struct {
Vars goflags.RuntimeMap
// Severities filters templates based on their severity and only run the matching ones.
Severities severity.Severities
// ExcludeSeverities specifies severities to exclude
ExcludeSeverities severity.Severities
// Author filters templates based on their author and only run the matching ones.
Author goflags.NormalizedStringSlice
// IncludeTags includes specified tags to be run even while being in denylist