mirror of https://github.com/daffainfo/nuclei.git
99 lines
2.8 KiB
Go
99 lines
2.8 KiB
Go
package parsers
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/catalog/loader/filter"
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/model"
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/templates"
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/utils"
|
|
"gopkg.in/yaml.v2"
|
|
"io/ioutil"
|
|
"os"
|
|
)
|
|
|
|
const mandatoryFieldMissingTemplate = "mandatory '%s' field is missing"
|
|
|
|
// Load loads a template by parsing metadata and running
|
|
// all tag and path based filters on the template.
|
|
func Load(templatePath string, isWorkflow bool, workflowTags []string, tagFilter *filter.TagFilter) (bool, error) {
|
|
template, templateParseError := parseTemplate(templatePath)
|
|
if templateParseError != nil {
|
|
return false, templateParseError
|
|
}
|
|
|
|
templateInfo := template.Info
|
|
if validationError := validateMandatoryInfoFields(templateInfo); validationError != nil {
|
|
return false, validationError
|
|
}
|
|
|
|
if utils.IsNotEmpty(template.Workflows) {
|
|
if isWorkflow {
|
|
return true, nil // if a workflow is declared and this template is a workflow, then load
|
|
} else {
|
|
return false, nil // if a workflow is declared and this template is not a workflow then do not load
|
|
}
|
|
} else if isWorkflow {
|
|
return false, nil // if no workflows are declared and this template is a workflow then do not load
|
|
} else { // if workflows are not declared and the template is not a workflow then parse it
|
|
return isInfoMetadataMatch(tagFilter, templateInfo, workflowTags)
|
|
}
|
|
}
|
|
|
|
func isInfoMetadataMatch(tagFilter *filter.TagFilter, templateInfo model.Info, workflowTags []string) (bool, error) {
|
|
templateTags := templateInfo.Tags.ToSlice()
|
|
templateAuthors := templateInfo.Authors.ToSlice()
|
|
templateSeverity := templateInfo.SeverityHolder.Severity
|
|
|
|
var match bool
|
|
var err error
|
|
if utils.IsEmpty(workflowTags) {
|
|
match, err = tagFilter.Match(templateTags, templateAuthors, templateSeverity)
|
|
} else {
|
|
match, err = tagFilter.MatchWithWorkflowTags(templateTags, templateAuthors, templateSeverity, workflowTags)
|
|
}
|
|
|
|
if err == filter.ErrExcluded {
|
|
return false, filter.ErrExcluded
|
|
}
|
|
|
|
return match, nil
|
|
}
|
|
|
|
func validateMandatoryInfoFields(info model.Info) error {
|
|
if utils.IsEmpty(info) {
|
|
return errors.New(fmt.Sprintf(mandatoryFieldMissingTemplate, "info"))
|
|
}
|
|
|
|
if utils.IsEmpty(info.Name) {
|
|
return errors.New(fmt.Sprintf(mandatoryFieldMissingTemplate, "name"))
|
|
}
|
|
|
|
authors := info.Authors.ToSlice()
|
|
if utils.IsEmpty(authors) {
|
|
return errors.New(fmt.Sprintf(mandatoryFieldMissingTemplate, "author"))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func parseTemplate(templatePath string) (*templates.Template, error) {
|
|
f, err := os.Open(templatePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer f.Close()
|
|
|
|
data, err := ioutil.ReadAll(f)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
template := &templates.Template{}
|
|
err = yaml.NewDecoder(bytes.NewReader(data)).Decode(template)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return template, nil
|
|
}
|