Skip to content

Commit b68de46

Browse files
committed
feat(security): run all detectors concurrently with sorted output
1 parent ceceab0 commit b68de46

1 file changed

Lines changed: 84 additions & 0 deletions

File tree

internal/engine/security/runner.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package security
2+
3+
import (
4+
"sort"
5+
"sync"
6+
7+
"github.com/hamza-hafeez82/cortex/pkg/detector"
8+
"github.com/hamza-hafeez82/cortex/pkg/detector/detectors"
9+
)
10+
11+
// Runner executes all security detectors concurrently and collects results.
12+
type Runner struct {
13+
detectors []detector.Detector
14+
}
15+
16+
// NewRunner creates a security Runner pre-loaded with all built-in detectors.
17+
func NewRunner() *Runner {
18+
return &Runner{
19+
detectors: []detector.Detector{
20+
&detectors.HardcodedSecretsDetector{},
21+
&detectors.SQLInjectionDetector{},
22+
&detectors.CommandInjectionDetector{},
23+
&detectors.PathTraversalDetector{},
24+
&detectors.InsecureRandomDetector{},
25+
&detectors.JWTMisconfigDetector{},
26+
&detectors.CORSMisconfigDetector{},
27+
&detectors.SensitiveDataInLogsDetector{},
28+
&detectors.VulnerableDepsDetector{},
29+
},
30+
}
31+
}
32+
33+
// Run executes all detectors in parallel and returns merged, sorted results.
34+
func (r *Runner) Run(ctx *detector.ScanContext) []detector.Issue {
35+
results := make(chan []detector.Issue, len(r.detectors))
36+
var wg sync.WaitGroup
37+
38+
for _, d := range r.detectors {
39+
wg.Add(1)
40+
go func(d detector.Detector) {
41+
defer wg.Done()
42+
results <- d.Run(ctx)
43+
}(d)
44+
}
45+
46+
go func() {
47+
wg.Wait()
48+
close(results)
49+
}()
50+
51+
var all []detector.Issue
52+
for issues := range results {
53+
all = append(all, issues...)
54+
}
55+
56+
sort.Slice(all, func(i, j int) bool {
57+
si := severityOrder(all[i].Severity)
58+
sj := severityOrder(all[j].Severity)
59+
if si != sj {
60+
return si < sj
61+
}
62+
if all[i].File != all[j].File {
63+
return all[i].File < all[j].File
64+
}
65+
return all[i].Line < all[j].Line
66+
})
67+
68+
return all
69+
}
70+
71+
func severityOrder(s string) int {
72+
switch s {
73+
case detector.SeverityCritical:
74+
return 0
75+
case detector.SeverityHigh:
76+
return 1
77+
case detector.SeverityMedium:
78+
return 2
79+
case detector.SeverityLow:
80+
return 3
81+
default:
82+
return 4
83+
}
84+
}

0 commit comments

Comments
 (0)