nuclei
nuclei copied to clipboard
Fatal error: concurrent map iteration and map write
Nuclei version: 2.7.3
Steps To Reproduce:
docker run -it -v /root:/root --rm projectdiscovery/nuclei -t /root/test.yaml -l input_urls.txt -stats
test.yaml
id: test
info:
name: test
author: tester
requests:
- method: GET
path:
- "{{BaseURL}}/"
This ticket was created based on p1734543's message on Discord.
Just had a quick look at this and I might be missing something obvious, but this is what I believe is happening /cc @ehsandeep
https://github.com/projectdiscovery/nuclei/blob/dev/v2/pkg/types/resume.go#L25-L39
// ResumeCfg contains the scan progression
type ResumeCfg struct {
sync.RWMutex
ResumeFrom map[string]*ResumeInfo `json:"resumeFrom"`
Current map[string]*ResumeInfo `json:"-"`
}
type ResumeInfo struct {
sync.RWMutex
Completed bool `json:"completed"`
InFlight map[uint32]struct{} `json:"inFlight"`
SkipUnder uint32 `json:"-"`
Repeat map[uint32]struct{} `json:"-"`
DoAbove uint32 `json:"-"`
}
Each type has its own mutex. However, when saving the configuration, only one is locked.
https://github.com/projectdiscovery/nuclei/blob/dev/v2/internal/runner/runner.go#L578-L587
// SaveResumeConfig to file
func (r *Runner) SaveResumeConfig(path string) error {
resumeCfg := types.NewResumeCfg()
r.resumeCfg.Lock()
resumeCfg.ResumeFrom = r.resumeCfg.Current
data, _ := json.MarshalIndent(resumeCfg, "", "\t")
r.resumeCfg.Unlock()
return os.WriteFile(path, data, os.ModePerm)
}
Access to ResumeCfg.ResumeFrom should be seiralized via custom ResumeFrom methods. It should be unexported to avoid unserialized accesses to it.