Skip to content

Commit 75525ed

Browse files
committed
fix(loader): replace panic with error handling in template loader
Replace panic with proper error return when dialers are missing, allowing callers to handle the situation gracefully. Changes: - Modify LoadTemplatesWithTags to return ([]*templates.Template, error) - Modify LoadTemplates to return ([]*templates.Template, error) - Modify Load to return error - Replace panic("dialers with executionId...") with fmt.Errorf - Replace panic("could not create wait group") with fmt.Errorf - Update all callers to handle the new error return Callers updated: - internal/runner/lazy.go - internal/runner/runner.go - internal/server/nuclei_sdk.go - lib/multi.go - lib/sdk.go - cmd/integration-test/library.go - pkg/protocols/common/automaticscan/util.go - pkg/catalog/loader/loader_bench_test.go Fixes #6674
1 parent 8aa427a commit 75525ed

9 files changed

Lines changed: 46 additions & 24 deletions

File tree

cmd/integration-test/library.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ func executeNucleiAsLibrary(templatePath, templateURL string) ([]string, error)
132132
if err != nil {
133133
return nil, errors.Wrap(err, "could not create loader")
134134
}
135-
store.Load()
135+
if err := store.Load(); err != nil {
136+
return nil, errors.Wrap(err, "could not load templates")
137+
}
136138

137139
_ = engine.Execute(context.Background(), store.Templates(), provider.NewSimpleInputProviderWithUrls(defaultOpts.ExecutionId, templateURL))
138140
engine.WorkPool().Wait() // Wait for the scan to finish

internal/runner/lazy.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ func GetAuthTmplStore(opts *types.Options, catalog catalog.Catalog, execOpts *pr
6767
// GetLazyAuthFetchCallback returns a lazy fetch callback for auth secrets
6868
func GetLazyAuthFetchCallback(opts *AuthLazyFetchOptions) authx.LazyFetchSecret {
6969
return func(d *authx.Dynamic) error {
70-
tmpls := opts.TemplateStore.LoadTemplates([]string{d.TemplatePath})
70+
tmpls, err := opts.TemplateStore.LoadTemplates([]string{d.TemplatePath})
71+
if err != nil {
72+
return fmt.Errorf("failed to load templates: %w", err)
73+
}
7174
if len(tmpls) == 0 {
7275
return fmt.Errorf("%w for path: %s", disk.ErrNoTemplatesFound, d.TemplatePath)
7376
}
@@ -140,9 +143,9 @@ func GetLazyAuthFetchCallback(opts *AuthLazyFetchOptions) authx.LazyFetchSecret
140143
// log result of template in result file/screen
141144
_ = writer.WriteResult(e, opts.ExecOpts.Output, opts.ExecOpts.Progress, opts.ExecOpts.IssuesClient)
142145
}
143-
_, err := tmpl.Executer.ExecuteWithResults(ctx)
144-
if err != nil {
145-
finalErr = err
146+
_, execErr := tmpl.Executer.ExecuteWithResults(ctx)
147+
if execErr != nil {
148+
finalErr = execErr
146149
}
147150
// store extracted result in auth context
148151
d.Extracted = data

internal/runner/runner.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,9 @@ func (r *Runner) RunEnumeration() error {
660660
}
661661
return nil // exit
662662
}
663-
store.Load()
663+
if err := store.Load(); err != nil {
664+
return err
665+
}
664666
// TODO: remove below functions after v3 or update warning messages
665667
templates.PrintDeprecatedProtocolNameMsgIfApplicable(r.options.Silent, r.options.Verbose)
666668

internal/server/nuclei_sdk.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ func newNucleiExecutor(opts *NucleiExecutorOptions) (*nucleiExecutor, error) {
125125
if err != nil {
126126
return nil, errors.Wrap(err, "Could not create loader options.")
127127
}
128-
store.Load()
128+
if err := store.Load(); err != nil {
129+
return nil, errors.Wrap(err, "Could not load templates.")
130+
}
129131

130132
return &nucleiExecutor{
131133
engine: executorEngine,

lib/multi.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ func (e *ThreadSafeNucleiEngine) ExecuteNucleiWithOptsCtx(ctx context.Context, t
150150
if err != nil {
151151
return errkit.Wrapf(err, "Could not create loader client: %s", err)
152152
}
153-
store.Load()
153+
if err := store.Load(); err != nil {
154+
return errkit.Wrapf(err, "Could not load templates: %s", err)
155+
}
154156

155157
inputProvider := provider.NewSimpleInputProviderWithUrls(e.eng.opts.ExecutionId, targets...)
156158

lib/sdk.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ func (e *NucleiEngine) LoadAllTemplates() error {
110110
if err != nil {
111111
return errkit.Wrapf(err, "Could not create loader client: %s", err)
112112
}
113-
e.store.Load()
113+
if err := e.store.Load(); err != nil {
114+
return errkit.Wrapf(err, "Could not load templates: %s", err)
115+
}
114116
e.templatesLoaded = true
115117
return nil
116118
}

pkg/catalog/loader/loader.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,14 @@ func (store *Store) RegisterPreprocessor(preprocessor templates.Preprocessor) {
333333

334334
// Load loads all the templates from a store, performs filtering and returns
335335
// the complete compiled templates for a nuclei execution configuration.
336-
func (store *Store) Load() {
337-
store.templates = store.LoadTemplates(store.finalTemplates)
336+
func (store *Store) Load() error {
337+
templates, err := store.LoadTemplates(store.finalTemplates)
338+
if err != nil {
339+
return err
340+
}
341+
store.templates = templates
338342
store.workflows = store.LoadWorkflows(store.finalWorkflows)
343+
return nil
339344
}
340345

341346
var templateIDPathMap map[string]string
@@ -637,7 +642,7 @@ func isParsingError(store *Store, message string, template string, err error) bo
637642
}
638643

639644
// LoadTemplates takes a list of templates and returns paths for them
640-
func (store *Store) LoadTemplates(templatesList []string) []*templates.Template {
645+
func (store *Store) LoadTemplates(templatesList []string) ([]*templates.Template, error) {
641646
return store.LoadTemplatesWithTags(templatesList, nil)
642647
}
643648

@@ -668,7 +673,8 @@ func (store *Store) LoadWorkflows(workflowsList []string) []*templates.Template
668673

669674
// LoadTemplatesWithTags takes a list of templates and extra tags
670675
// returning templates that match.
671-
func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) []*templates.Template {
676+
// Returns an error if dialers are not initialized for the given execution ID.
677+
func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) ([]*templates.Template, error) {
672678
defer store.saveMetadataIndexOnce()
673679

674680
indexFilter := store.indexFilter
@@ -708,7 +714,7 @@ func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) []*templ
708714

709715
wgLoadTemplates, errWg := syncutil.New(syncutil.WithSize(concurrency))
710716
if errWg != nil {
711-
panic("could not create wait group")
717+
return nil, fmt.Errorf("could not create wait group: %w", errWg)
712718
}
713719

714720
if typesOpts.ExecutionId == "" {
@@ -717,7 +723,7 @@ func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) []*templ
717723

718724
dialers := protocolstate.GetDialersWithId(typesOpts.ExecutionId)
719725
if dialers == nil {
720-
panic("dialers with executionId " + typesOpts.ExecutionId + " not found")
726+
return nil, fmt.Errorf("dialers with executionId %s not found", typesOpts.ExecutionId)
721727
}
722728

723729
for _, templatePath := range includedTemplates {
@@ -852,7 +858,7 @@ func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) []*templ
852858
return loadedTemplates.Slice[i].Path < loadedTemplates.Slice[j].Path
853859
})
854860

855-
return loadedTemplates.Slice
861+
return loadedTemplates.Slice, nil
856862
}
857863

858864
// IsHTTPBasedProtocolUsed returns true if http/headless protocol is being used for

pkg/catalog/loader/loader_bench_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
7171
b.ReportAllocs()
7272

7373
for b.Loop() {
74-
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
74+
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
7575
}
7676
})
7777

@@ -89,7 +89,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
8989
b.ReportAllocs()
9090

9191
for b.Loop() {
92-
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
92+
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
9393
}
9494
})
9595

@@ -107,7 +107,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
107107
b.ReportAllocs()
108108

109109
for b.Loop() {
110-
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
110+
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
111111
}
112112
})
113113

@@ -125,7 +125,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
125125
b.ReportAllocs()
126126

127127
for b.Loop() {
128-
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
128+
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
129129
}
130130
})
131131

@@ -143,7 +143,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
143143
b.ReportAllocs()
144144

145145
for b.Loop() {
146-
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
146+
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
147147
}
148148
})
149149

@@ -161,7 +161,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
161161
b.ReportAllocs()
162162

163163
for b.Loop() {
164-
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
164+
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
165165
}
166166
})
167167

@@ -181,7 +181,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
181181
b.ReportAllocs()
182182

183183
for b.Loop() {
184-
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
184+
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
185185
}
186186
})
187187
}

pkg/protocols/common/automaticscan/util.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ func getTemplateDirs(opts Options) ([]string, error) {
3737

3838
// LoadTemplatesWithTags loads and returns templates with given tags
3939
func LoadTemplatesWithTags(opts Options, templateDirs []string, tags []string, logInfo bool) ([]*templates.Template, error) {
40-
finalTemplates := opts.Store.LoadTemplatesWithTags(templateDirs, tags)
40+
finalTemplates, err := opts.Store.LoadTemplatesWithTags(templateDirs, tags)
41+
if err != nil {
42+
return nil, errors.Wrap(err, "could not load templates")
43+
}
4144
if len(finalTemplates) == 0 {
4245
return nil, errors.New("could not find any templates with tech tag")
4346
}

0 commit comments

Comments
 (0)