diff --git a/pkg/catalog/loader/loader.go b/pkg/catalog/loader/loader.go index d7648073a1..19aa590970 100644 --- a/pkg/catalog/loader/loader.go +++ b/pkg/catalog/loader/loader.go @@ -172,6 +172,9 @@ func New(cfg *Config) (*Store, error) { // Initialize metadata index and filter (load from disk & cache for reuse) store.metadataIndex = store.loadTemplatesIndex() store.indexFilter = store.buildIndexFilter() + if cfg.ExecutorOptions != nil { + cfg.ExecutorOptions.TemplateVerificationCallback = store.getTemplateVerification + } store.saveMetadataIndexOnce = sync.OnceFunc(func() { if store.metadataIndex == nil { return @@ -246,6 +249,22 @@ func New(cfg *Config) (*Store, error) { return store, nil } +func (store *Store) getTemplateVerification(templatePath string) *protocols.TemplateVerification { + if store.metadataIndex == nil { + return nil + } + + metadata, found := store.metadataIndex.Get(templatePath) + if !found { + return nil + } + + return &protocols.TemplateVerification{ + Verified: metadata.Verified, + Verifier: metadata.TemplateVerifier, + } +} + func handleTemplatesEditorURLs(input string) string { parsed, err := url.Parse(input) if err != nil { diff --git a/pkg/protocols/protocols.go b/pkg/protocols/protocols.go index cb29f1258f..bf2d8ca00c 100644 --- a/pkg/protocols/protocols.go +++ b/pkg/protocols/protocols.go @@ -57,6 +57,12 @@ type Executer interface { ExecuteWithResults(ctx *scan.ScanContext) ([]*output.ResultEvent, error) } +// TemplateVerification holds cached verification information for a template. +type TemplateVerification struct { + Verified bool + Verifier string +} + // ExecutorOptions contains the configuration options for executer clients type ExecutorOptions struct { // TemplateID is the ID of the template for the request @@ -67,6 +73,9 @@ type ExecutorOptions struct { TemplateInfo model.Info // TemplateVerifier is the verifier for the template TemplateVerifier string + // TemplateVerificationCallback returns cached verification info for a template path. + // If it returns nil, verification should be computed normally. + TemplateVerificationCallback func(templatePath string) *TemplateVerification // RawTemplate is the raw template for the request RawTemplate []byte // Output is a writer interface for writing output events from executer. @@ -266,6 +275,7 @@ func (e *ExecutorOptions) Copy() *ExecutorOptions { TemplatePath: e.TemplatePath, TemplateInfo: e.TemplateInfo, TemplateVerifier: e.TemplateVerifier, + TemplateVerificationCallback: e.TemplateVerificationCallback, RawTemplate: e.RawTemplate, Output: e.Output, Options: e.Options, diff --git a/pkg/templates/compile.go b/pkg/templates/compile.go index 7060023161..fcbf2eb54a 100644 --- a/pkg/templates/compile.go +++ b/pkg/templates/compile.go @@ -580,6 +580,19 @@ func parseTemplate(data []byte, srcOptions *protocols.ExecutorOptions) (*Templat // check if the template is verified // only valid templates can be verified or signed + if options.TemplateVerificationCallback != nil && options.TemplatePath != "" { + if cached := options.TemplateVerificationCallback(options.TemplatePath); cached != nil { + template.Verified = cached.Verified + template.TemplateVerifier = cached.Verifier + options.TemplateVerifier = cached.Verifier + //nolint + if !(template.Verified && template.TemplateVerifier == "projectdiscovery/nuclei-templates") { + template.Options.RawTemplate = data + } + return template, nil + } + } + var verifier *signer.TemplateSigner for _, verifier = range signer.DefaultTemplateVerifiers { template.Verified, _ = verifier.Verify(data, template) @@ -592,10 +605,12 @@ func parseTemplate(data []byte, srcOptions *protocols.ExecutorOptions) (*Templat } } options.TemplateVerifier = template.TemplateVerifier + //nolint if !(template.Verified && verifier.Identifier() == "projectdiscovery/nuclei-templates") { template.Options.RawTemplate = data } + return template, nil }