Skip to content

Commit d1e719d

Browse files
authored
Fix QuantityIncreasesRisk edge case with only high behaviors present (#1055)
Signed-off-by: egibs <20933572+egibs@users.noreply.github.com>
1 parent b937024 commit d1e719d

2 files changed

Lines changed: 17 additions & 18 deletions

File tree

pkg/action/scan.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,15 @@ func scanSinglePath(ctx context.Context, c malcontent.Config, path string, ruleF
174174
// This is a short-circuit that avoids any report generation logic
175175
risk := report.HighestMatchRisk(mrs)
176176
threshold := max(3, c.MinFileRisk, c.MinRisk)
177-
if c.Scan && risk < threshold {
177+
if c.Scan && risk < threshold && !c.QuantityIncreasesRisk {
178178
fr := &malcontent.FileReport{Skipped: "overall risk too low for scan", Path: path}
179179
if isArchive {
180180
os.RemoveAll(path)
181181
}
182182
return fr, nil
183183
}
184184

185-
fr, err := report.Generate(ctx, path, mrs, c, archiveRoot, logger, fc, kind)
185+
fr, err := report.Generate(ctx, path, mrs, c, archiveRoot, logger, fc, kind, risk)
186186
if err != nil {
187187
return nil, NewFileReportError(err, path, TypeGenerateError)
188188
}

pkg/report/report.go

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ func fileMatchesRule(meta []yarax.Metadata, ext string) bool {
377377
return true
378378
}
379379

380-
func Generate(ctx context.Context, path string, mrs *yarax.ScanResults, c malcontent.Config, expath string, _ *clog.Logger, fc []byte, kind *programkind.FileType) (*malcontent.FileReport, error) {
380+
func Generate(ctx context.Context, path string, mrs *yarax.ScanResults, c malcontent.Config, expath string, _ *clog.Logger, fc []byte, kind *programkind.FileType, highestRisk int) (*malcontent.FileReport, error) {
381381
if ctx.Err() != nil {
382382
return &malcontent.FileReport{}, ctx.Err()
383383
}
@@ -408,7 +408,6 @@ func Generate(ctx context.Context, path string, mrs *yarax.ScanResults, c malcon
408408
risk := 0
409409
riskCounts := make(map[int]int, 0)
410410

411-
highestRisk := HighestMatchRisk(mrs)
412411
// Store match rules in a map for future override operations
413412
mrsMap := createMatchRulesMap(mrs, matchCount)
414413

@@ -435,9 +434,9 @@ func Generate(ctx context.Context, path string, mrs *yarax.ScanResults, c malcon
435434
switch {
436435
case risk == -1:
437436
continue
438-
case risk < minScore && !ignoreMalcontent && !override:
437+
case !c.Scan && risk < minScore && !ignoreMalcontent && !override:
439438
continue
440-
case c.Scan && risk < highestRisk && !ignoreMalcontent && !override:
439+
case c.Scan && risk < highestRisk && !c.QuantityIncreasesRisk && !ignoreMalcontent && !override:
441440
continue
442441
}
443442

@@ -483,13 +482,15 @@ func Generate(ctx context.Context, path string, mrs *yarax.ScanResults, c malcon
483482
}
484483

485484
// Update the behaviors to account for overrides
486-
fr.Behaviors = handleOverrides(fr.Behaviors, fr.Overrides, minScore)
485+
fr.Behaviors = handleOverrides(fr.Behaviors, fr.Overrides, minScore, c.Scan, c.QuantityIncreasesRisk)
487486

488487
// Adjust the overall risk if we deviated from overallRiskScore
489488
// Scans will still need to drop <= medium results
490-
newRisk := highestBehaviorRisk(fr)
491-
if overallRiskScore != newRisk {
492-
overallRiskScore = newRisk
489+
overallRiskScore = highestBehaviorRisk(fr)
490+
491+
// If something has a lot of high, it's probably critical
492+
if c.QuantityIncreasesRisk && upgradeRisk(ctx, overallRiskScore, riskCounts, size) {
493+
overallRiskScore = CRITICAL
493494
}
494495

495496
if c.Scan && overallRiskScore < HIGH {
@@ -503,11 +504,6 @@ func Generate(ctx context.Context, path string, mrs *yarax.ScanResults, c malcon
503504
fr.Skipped = "ignoring malcontent binary"
504505
}
505506

506-
// If something has a lot of high, it's probably critical
507-
if c.QuantityIncreasesRisk && upgradeRisk(ctx, overallRiskScore, riskCounts, size) {
508-
overallRiskScore = 4
509-
}
510-
511507
slices.Sort(pledges)
512508
slices.Sort(syscalls)
513509
slices.Sort(caps)
@@ -732,8 +728,6 @@ func upgradeRisk(ctx context.Context, riskScore int, riskCounts map[int]int, siz
732728
upgrade = true
733729
case highCount > 6:
734730
upgrade = true
735-
case !upgrade:
736-
upgrade = false
737731
}
738732

739733
clog.DebugContextf(ctx, "upgrading risk: high=%d, size=%d", highCount, size)
@@ -779,7 +773,7 @@ func highestBehaviorRisk(fr *malcontent.FileReport) int {
779773
}
780774

781775
// handleOverrides modifies the behavior slice based on the contents of the override slice.
782-
func handleOverrides(original, override []*malcontent.Behavior, minScore int) []*malcontent.Behavior {
776+
func handleOverrides(original, override []*malcontent.Behavior, minScore int, scan, quantityIncreasesRisk bool) []*malcontent.Behavior {
783777
behaviorMap := make(map[string]*malcontent.Behavior, len(original))
784778
for _, b := range original {
785779
behaviorMap[b.RuleName] = b
@@ -798,6 +792,11 @@ func handleOverrides(original, override []*malcontent.Behavior, minScore int) []
798792

799793
modified := make([]*malcontent.Behavior, 0, len(behaviorMap))
800794
for _, b := range behaviorMap {
795+
// if running a scan and using quantityIncreasesRisk,
796+
// append every behavior so we can handle filtering correctly
797+
if scan && quantityIncreasesRisk && b.RiskScore >= HIGH {
798+
modified = append(modified, b)
799+
}
801800
if b.RiskScore >= minScore {
802801
modified = append(modified, b)
803802
}

0 commit comments

Comments
 (0)