122 lines
3.8 KiB
YAML
122 lines
3.8 KiB
YAML
- id: go-cor-001
|
|
title: "Goroutine launched without synchronisation"
|
|
severity: medium
|
|
languages: [go]
|
|
tags: [correctness, concurrency]
|
|
pattern: 'go\s+func\s*\('
|
|
exclude_pattern: 'wg\.|\.Go\(|context\.|done\s*<-|select\s*\{'
|
|
fix: "Use a WaitGroup, errgroup, or context cancellation to track goroutine lifecycle"
|
|
found_in: [go-process]
|
|
example_bad: 'go func() { doWork() }()'
|
|
example_good: 'wg.Add(1); go func() { defer wg.Done(); doWork() }()'
|
|
first_seen: "2026-03-09"
|
|
detection: regex
|
|
auto_fixable: false
|
|
|
|
- id: go-cor-002
|
|
title: "WaitGroup.Wait without timeout or context"
|
|
severity: low
|
|
languages: [go]
|
|
tags: [correctness, concurrency]
|
|
pattern: '\.Wait\(\)'
|
|
exclude_pattern: 'select\s*\{|ctx\.Done|context\.With|time\.After'
|
|
fix: "Wrap Wait() in a select with context.Done() or time.After() to prevent indefinite blocking"
|
|
found_in: [go-process]
|
|
example_bad: 'wg.Wait()'
|
|
example_good: |
|
|
done := make(chan struct{})
|
|
go func() { wg.Wait(); close(done) }()
|
|
select {
|
|
case <-done:
|
|
case <-ctx.Done():
|
|
}
|
|
first_seen: "2026-03-09"
|
|
detection: regex
|
|
auto_fixable: false
|
|
|
|
- id: go-cor-003
|
|
title: "Silent error swallowing with blank identifier"
|
|
severity: medium
|
|
languages: [go]
|
|
tags: [correctness, errors]
|
|
pattern: '^\s*_\s*=\s*\w+\.\w+\('
|
|
exclude_pattern: 'defer|Close\(|Flush\('
|
|
fix: "Handle the error explicitly — log it, return it, or document why it is safe to discard"
|
|
found_in: [go-store, go-cache]
|
|
example_bad: '_ = service.Process(data)'
|
|
example_good: |
|
|
if err := service.Process(data); err != nil {
|
|
return fmt.Errorf("processing: %w", err)
|
|
}
|
|
first_seen: "2026-03-09"
|
|
detection: regex
|
|
auto_fixable: false
|
|
|
|
- id: go-cor-004
|
|
title: "Panic in library code"
|
|
severity: high
|
|
languages: [go]
|
|
tags: [correctness, panic]
|
|
pattern: '\bpanic\('
|
|
exclude_pattern: '_test\.go|// unreachable|Must\w+\('
|
|
fix: "Return an error instead of panicking — panics in libraries crash the caller"
|
|
found_in: [go-io, go-config]
|
|
example_bad: 'panic("unexpected state")'
|
|
example_good: 'return fmt.Errorf("unexpected state: %v", state)'
|
|
first_seen: "2026-03-09"
|
|
detection: regex
|
|
auto_fixable: false
|
|
|
|
- id: go-cor-005
|
|
title: "File deletion without path validation"
|
|
severity: high
|
|
languages: [go]
|
|
tags: [correctness, filesystem]
|
|
pattern: 'os\.Remove(All)?\('
|
|
exclude_pattern: 'filepath\.Clean|ValidatePath|strings\.Contains.*\.\.'
|
|
fix: "Validate the path before deletion to prevent removing unintended files or directories"
|
|
found_in: [go-io]
|
|
example_bad: 'os.RemoveAll(userProvidedPath)'
|
|
example_good: |
|
|
cleanPath := filepath.Clean(userProvidedPath)
|
|
if !strings.HasPrefix(cleanPath, safeBase) {
|
|
return fmt.Errorf("path outside safe directory")
|
|
}
|
|
os.RemoveAll(cleanPath)
|
|
first_seen: "2026-03-09"
|
|
detection: regex
|
|
auto_fixable: false
|
|
|
|
- id: go-cor-006
|
|
title: "HTTP response error discarded"
|
|
severity: high
|
|
languages: [go]
|
|
tags: [correctness, errors, http]
|
|
pattern: 'resp,\s*_\s*:=.*\.(Get|Post|Do|Send)\('
|
|
fix: "Always check the error from HTTP calls — network failures are common"
|
|
found_in: [go-api]
|
|
example_bad: 'resp, _ := http.Get(url)'
|
|
example_good: |
|
|
resp, err := http.Get(url)
|
|
if err != nil {
|
|
return fmt.Errorf("fetching %s: %w", url, err)
|
|
}
|
|
defer resp.Body.Close()
|
|
first_seen: "2026-03-09"
|
|
detection: regex
|
|
auto_fixable: false
|
|
|
|
- id: go-cor-007
|
|
title: "Wrong signal type (syscall.Signal instead of os.Signal)"
|
|
severity: low
|
|
languages: [go]
|
|
tags: [correctness, portability]
|
|
pattern: 'syscall\.Signal\b'
|
|
exclude_pattern: 'os\.Signal'
|
|
fix: "Use os.Signal for portable signal handling across platforms"
|
|
found_in: [go-process]
|
|
example_bad: 'ch := make(chan syscall.Signal, 1)'
|
|
example_good: 'ch := make(chan os.Signal, 1)'
|
|
first_seen: "2026-03-09"
|
|
detection: regex
|
|
auto_fixable: true
|